求两个数的最小公约数经常使用辗转相除法。
代码很简单,如下所示:
#include<stdio.h>
int main()
{
int M,N;
scanf("%d %d",&M,&N);
int a=M,b=N;
if(M<N)//先调整大小,使M为两数中较大者,N为较小者
{
int t=M;
M=N;
N=t;
}
int r=M%N;//求得余数
while(r!=0)
{
M=N;
N=r;
r=M%N;
}//当r不为0,退出循环,得到N为最大公约数
M=a*b/N;//M为最小公倍数
printf("%d %d\n",N,M);//打印最大公约数,最小公倍数
return 0;
}
但道理却有点绕,我们应当去追寻其本质的道理,溯其根本才得以善用之。
设有未知数X和Y,且X>Y,现求其最大公约数(能同时整除X和Y的最大的自然数),
X/Y 商Q 余R,解答问题的关键条件在于:若X和Y存在公约数Z(不要求是是最大公约数),则对任意mX+nY都能被Z整除,即Z是(mX+nY)的因数。
若R==0,我们可以轻易知道最大公约数就是除数Y
若R!=0,可得X-QY(为mX+nY的结构其中m=1,n=-Q)=R>0,由上可知,X和Y的公约数Z必定为R的因数。得出结论:Z是X、Y、R的公约数!!!
现在假设Z不仅是X和Y的公约数,还是X和Y的最大公约数。那么Z是Y和R的公约数的基础上,Z还会是Y和R最大的公约数嘛????
假设Y和R存在最大公约数为N非Z,则必有N>Z。则由上述关键条件知道:X=R+QY的约数必定有N,又N为Y的约数,所以有X和Y的最大公约数为N>Z,与前面条件:X和Y的最大公约数为Z相矛盾。所以推理得到Y和R不存在大于Z的公约数,即Z是Y和R的最大公约数!!
综上,(X,Y)=Z且(Y,R)=Z且其中(X>Y>R),Z为三者的最大公约数。
推论:被除数X和除数Y的最大公约数为除数Y和余数R=X%Y的最大公约数!
现令X=Y,Y=R。重复X/Y=商Q余D,
若D!=0 ,最大公约数Z=(X,Y)=(Y,R)=(R,D),我们通过不断缩小范文寻找最大公约数Z
若D==0,Y和R的最大公约数为R,(X,Y)=(Y,R)=Z=R
求最大公约数的辗转相除算法为:
- 比较M和N大小,使M为较大者
- R=M%N,R为M取N的余数
- 若R==0,易知M和N的最大公约数为N
- 若R!=0,令M=N,N=R,跳到(2)