欧几里得与扩展欧几里得


1欧几里得算法

欧几里得算法(辗转相除法)是解决两个数,a,b的最大共因数的(最大公约数)

中国古代有个       更相减损术(高中课本学过)与此同理


先不管他们那不明觉厉的名字。。。。。看一下思想


假设a,b的最大共因数为gdc

那么    a=k1*gcd,b=k2*gcd

不妨假设a>b(不影响)

         则   a=b*t+c

等号两侧同除gcd,因为a/gcd为整数,b*t/gcd为整数

所以c/gcd也为整数

这样a与b的最大共因数也是b与c的最大共因数

即gcd(a,b)==gcd(b,c)=gcd(b,a%b)

int Gcd(int a,int b)
{
    if(a<b)
    {
        int tem=a;
        a=b,b=tem;
    }
    if(!b)
        return a;
    return Gcd(b,a%b);
}

扩展欧几里得解决的是    ax+by=c    这样的二元一次方程的x,y的解


ax+by=gcd(a,b)一定有(x,y)的整数解,


首先,在欧几里得算法中最后一步会求到gcd(b,a%b)中a%b==0的情况

这样a就是最大共因数

而在上式中    就是 a*1+b*0=gcd(a,0)即x=1,y=0

好啦,先把这放一放


来看一下怎么求解

ax+by=gcd(a,b)=gcd(b,a%b)

                            =bx0+(a%b)y0

                            =bx0+(a-a/b*b)y0

                            =b(x0-a/by0)+ay0

                            =ay0+b(x0-a/by0)

即x=y0,y=(x0-a/by0)——可以递归求(x,y)了(最终的xn=1,yn=0)


那这样,可以在之前的欧几里得算法的基础上添点东西

把(x,y)求出来了

int exgcd(int a,int b,int &x,int &y){
    if(b == 0)
    {//已知的特殊情况
        x = 1,y = 0;
        return a;
    }
    int d = exgcd(b,a%b,x,y);
    int t = x;                
    x = y,y = t - (a/b)*y;//代入公式
    return d;
}

猜你喜欢

转载自blog.csdn.net/du_mingm/article/details/79560513