欧几里得算法(最大公约数、最小公倍数,拓展欧几里得算法)

这三种算法都是由欧几里得算法得出的。欧几里得算法又称为辗转相除法。

1.最大公约数:

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);
}

2.最小公倍数

定理:x、y 两个数的最小公倍数乘以它们的最大公约数等于 x 和 y 本身的乘积。

即LCM(x,y)=(x*y)/GCD(x,y)

算法实现:

int lcm(int x,int y)
{
    return (x*y)/(gcd(x,y));
}

3.拓展欧几里得算法

扩展欧几里德算法是在已知 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;
}

4.LCM(a,b)=L;已知a,L,求b

根据前面我们已经知道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<

 

你可能感兴趣的:(欧几里得算法(最大公约数、最小公倍数,拓展欧几里得算法))