利用最大公约数求解问题

来源:互联网 发布:linux ping timeout 编辑:程序博客网 时间:2024/06/06 01:20

问题:求一个最小正整数n,使得对于2至10的所有数m,均有n%m=m-1,要求:不允许利用枚举法。

一.分析:

由n%m=m-1,得:n=qm+m-1,即n+1=(q+1)m(m>=2&&m<=10),故n+1是2至10所有数的公倍数。
要求最小正整数,取2至10的最小公倍数lcm使得n=lcm-1满足要求。

二.求解:

1.求2至10所有数的最大公约数:

求两数的最大公约数采用辗转相除法,即gcd(a,b)=gcd(b,r),r=a%b,直至r=0,得结果gcd(b',0)

=b'=gcd(a,b).
代码实现:
int gcd(int a,int b){
//求a与b的最大公约数

int temp;
while(b!=0){
temp=a%b;
a=b;
b=temp;
}
return a;
}

求一系列数的最大公约数,采用分步法,即gcd(a,b,c)=gcd(gcd(a,b),c)...
代码实现:
void yxlgcd(int* mult,int* gcd){
//求2,3,...,10的最大公约数,存入gcd中,mult表示他们的乘积

 int temp=2,i;
        *mult=2;
 for(i=3;i<=10;i++){
 *mult*=i;
 temp=gcd(temp,i);
 }
      *gcd=temp;
}

2.求2至10所有数的最小公倍数:

lcm(s,t)=s*t/gcd(s,t),故2至10所有数的最小公倍数为:lcm=mult/gcd;

3.该问题解为:n=lcm-1.

三.具体实现方案:

/////////////////////////////////////////////////////////////////////////////////////////////////

//
//  * 求一个最小正整数n,使得使得对于2至10的所有数m,均有n%m=m-1,要求:不允许利用枚举法。*//
/////////////////////////////////////////////////////////////////////////////////////////////////

//
#include<stdio.h>

int gcd(int a,int b){
    //求a与b的最大公约数
int temp;

while(b!=0){
temp=a%b;
a=b;
b=temp;
}
return a;
}

void yxlgcd(int* mult,int* gcdd){
 //求2,3,...,10的最大公约数,存入gcd中,mult表示他们的乘积
 int temp=2,i;
        *mult=2;

 for(i=3;i<=10;i++){
 *mult*=i;
 temp=gcd(temp,i);
 }
      *gcdd=temp;
}

int main(){

int mult=2,i,lcm,gcd,n;

yxlgcd(&mult,&gcd);
lcm=mult/gcd;
n=lcm-1;

printf("该数为:%d/n/n",n);

for(i=2;i<=10;i++)
printf("%d 除%d 余 %d/n",n,i,n%i);

printf("输入任意字符结束...");
getchar();
return 0;
}

四.运行结果:

该数为:3628799

3628799 除2 余 1
3628799 除3 余 2
3628799 除4 余 3
3628799 除5 余 4
3628799 除6 余 5
3628799 除7 余 6
3628799 除8 余 7
3628799 除9 余 8
3628799 除10 余 9
输入任意字符结束...

五.总结:
这个问题的求解并不难,关键是要分析出求2至10所有数的最小公倍数,突破口在于将n%m=m-1转换为n+1=qm.

 

-------------------------------------------------------------------------------------------------
注: 原创作品,切勿用于商业目的,否则责任必究! mail:lilinaust@live.cn
-------------------------------------------------------------------------------------------------

原创粉丝点击