涉及两个正整数
1.说明:
试求已知两个正整数a,b的最大公约数与最小公倍数;
为方便表述,记:(a,b)为正整数a,b的最大公约数,{a,b}为正整数a,b的最小公倍数;
为简化设计,可以应用a,b的最大公约数与最小公倍数的以下性质:
(a,b) * {a,b}=a * b
2.程序设计:
(1)、应用欧几里德算法设计;
求两个整数最大公约数的殴几里德算法由古希腊数学家殴几里德发明,也叫辗转相除法,是数论和代数学中的重要方法。
求两个正整数a,b(约定a>b)的最大公约数的殴几里德算法:
1). a 除以 b 得余数 r ,若r=0,则 b 为所求的最大公约数;
2).若 r!=0 ,以 b 为 a ,r 为 b ,继续步骤1)。
注意到任意两个正整数总存在最大公约数,上述辗转相除过程中余数会逐步变小,相除过程总会结束。
#include<stdio.h>
int main()
{
long a,b,c,r,a1,b1;
printf("请输入两个正整数a,b:");
scanf("%d,%d",&a,&b);
if(a<b)
{
c=a;
a=b; /*交换a,b,确保a>b*/
b=c;
}
a1=a;b1=b;
r=a%b;
while(r!=0)
{
a=b;b=r; /*实施辗转相除*/
r=a%b;
}
printf("最大公约数(%d,%d)=%ld\n",a1,b1,b);
printf("最小公倍数{%d,%d}=%ld\n",a1,b1,a1*b1/b);
}
(2)、按定义常规求解;
按最大公约数与最小公倍数的定义设计求解,显得更为直观,也更为方便。
设置c循环,c从b(即两个数中较小的那个)开始递减取值至1,若c同时是a,b的约数(最先出现的显然为最大公约数),则输出结果。
#include<stdio.h>
int main()
{
long a,b,c;
printf("请输入两个正整数啊a,b:");
scanf("%d,%d",&a,&b);
if(a<b)
{
c=a;
a=b;
b=c;
}
for(c=b;c>=1;c--) /*c为试商因数*/
if(a%c==0&&b%c==0)
break;
printf("最大公约数(%d,%d)=%ld\n",a,b,c);
printf("最小公倍数(%d,%d)=%ld\n",a,b,a*b/c);
}
3.程序运行示例及其注意事项:
请输入两个正整数a,b: 10920,21420
最大公约数(10920,21420)=420
最小公倍数{10920,21420}=556920
注意:保证题设条件a>b。
涉及多个正整数
拓展到求多个正整数的最大公约数与最小公倍数。
为方便表述,记 (a1,a2,……,an) 为n个正整数 a1,a2,……,an 的最大公约数, {a1,a2,……,an} 为n个正整数 a1,a2,……,an 的最小公倍数。
1.说明:
求3个或者3个以上的正整数的最大公约数与最小公倍数,可通过反复运用求两个正整数的最大公约数与最小公倍数的方法来实现。
对与3个或者3个以上的正整数,最大公约数与最小公倍数有以下性质:
(a1,a2,a3)=((a1,a2),a3)
(a1,a2,a3,a4)=((a1,a2,a3),a4),……
{a1,a2,a3}={{a1,a2},a3}
{a1,a2,a3,a4}={{a1,a2,a3},a4},……
应用这一性质,要求n个整数的最大公约数,先求出前n-1个整数的最大公约数b,再求出第n个数与b的最大公约数;要求n个整数的最小公倍数,先求出前n-1个整数的最小公倍数b,再求出第n个数与b的最小公倍数。
求n个数的最大公约数,为方便输出,设置m数组:
1).输入的n个正整数存储在m数组m[0],m[1],m[2],…,m[n-1]中;
2).开始时b=m[0],即输入的第一个数赋值给变量b;
3).进入k循环,每次把输入的数m[1]~m[n-1]赋值给a,求得a,b的最大公约数c。如果c=1,退出循环,即m数组的最大公约数为1;否则赋值给b,即b=c,为下轮运算做准备。
求n个数的最小公倍数与上述类似。
2.程序设计:
#include<stdio.h>
int main()
{
int k,n;
long a,b,c,m[100];
printf("请输入正整数个数n:");
scanf("%d",&n);
printf("请依此输入%d个正整数:",n);
for(k=0;k<=n-1;k++)
{
printf("\n请输入第%d个正整数:",k+1);
scanf("%ld",&m[k]); /*输入原始数据*/
}
b=m[0];
for(k=1;k<=n-1;k++) /*循环n-1次*/
{
a=m[k];
if(a<b)
{
c=a;
a=b; /*交换a、b,确保a>b*/
b=c;
}
for(c=b;c>=1;c--)
if(a%c==0&&b%c==0)
break; /*计算最大公约数*/
if(c==1)
break; /*如果求得最大公约数为1,退出循环*/
b=c;
}
printf("(%ld",m[0]);
for(k=1;k<=n-1;k++)
printf(",%ld",m[k]);
printf(")=%ld\n",c); /*输出最大公约数结果*/
b=m[0];
for(k=1;k<=n-1;k++) /*循环n-1次*/
{
a=m[k];
if(a<b)
{
c=a;
a=b;
b=c;
}
for(c=a;c<=a*b;c=c+a) /*按定义计算最小公倍数c*/
if(c%b==0)
break;
b=c;
}
printf("{%ld",m[0]);
for(k=1;k<=n-1;k++)
printf(",%ld",m[k]);
printf("}=%ld\n",c); /*输出最小公倍数*/
}
3.程序运行示例及其注意事项:
请输入正整数个数n: 3
请依次输入三个正整数:
请输入第1个正整数: 238
请输入第2个正整数: 782
请输入第3个正整数: 646
(238,782,646)=34
{238,782,646}=104006
注意:对n(n>=3)个正整数,不存在最大公约数与最小公倍数的乘积等于这n个正整数之积的性质,因此不能套用两个正整数的性质求n个数的最小公倍数,以防出错。