这三种算法都是由欧几里得算法得出的。欧几里得算法又称为辗转相除法。
GCD(x,y)=GCD(y,x mod y),x>y
算法实现:
int gcd(int x,int y)
{
if(y==0)
return x;
return gcd(y,x%y);
}
定理:x、y 两个数的最小公倍数乘以它们的最大公约数等于 x 和 y 本身的乘积。
即LCM(x,y)=(x*y)/GCD(x,y)
算法实现:
int lcm(int x,int y)
{
return (x*y)/(gcd(x,y));
}
扩展欧几里德算法是在已知 x、y 时,求解一组 a、b,使得 a*x+b*y=GCD(x,y)
分析:
当y=0时,GCD(x,y)=x,此时a=1,b=0;
当x>y>0时
设a1*x+b1*y=GCD(x,y),a2*x+b2*(x%y)=GCD(y,x%y)
因为GCD(x,y)=GCD(y,x%y),所以a1*x+b1*y=a2*y+b2*(x%y)
即a1*x+b1*y=a2*y+b2*(x-[x/y]*y)=b2*x+(a2-[x/y]*b2)*y
所以得出a1=b2,b1=a2-[x/y]*b2
因为递归总是会得到y=0,所以会得出a、b的值。
int Extended_GCD(int x,int y,int &a,int &b)
{
if(y==0)
{
a=1;
b=0;
return x;
}
int gcd=Extened_GCD(y,x%y,a,b);
int temp=a;
a=b;
b=temp-x/y*b;
return gcd;
}
根据前面我们已经知道ab=lcm*gcd,所以b=lcm/a*gcd,那么lcm/a一定是b的一个因子,只要gcd(a,b)==1,b就等于lcm/a了,即判断gcd(a,lcm/a)是否等于1.如果gcd(a,lcm/a)不等于1,说明ab有最小公因子,b可写为lcm/a*gcd(a,lcm/a)(因为lcm/a是b的因子,所以gcd(a,lcm/a)==gcd(a,b))此时将a/gcd(a,lcm/a),直到满足gcd(a,lcm/a)==1
int a,z;
cin>>a>>z;
int b=z/a;
while(gcd(a,b)!=1)
{
int g=gcd(a,b);
b*=g;
a/=g;
}
cout<