欧几里得、扩展欧几里得

推荐博客 :https://www.cnblogs.com/frog112111/archive/2012/08/19/2646012.html

欧几里得又称为辗转相除法,是用来求最大公约数的一种高效的算法。

核心就是一点 gcd(a, b) = gcd(b, a%b) ;

int gcd(int a, int b){
    if (b == 0) return a;
    return gcd(b, a%b);
}

 

扩展欧几里得

两个不定方程(扩展欧几里得算法作用之处)

定理:若ax+by=g,(g=gcd(a,b),即g是a,b的最大公约数)有整数解(x1,y1)

  则ax+by=c(c是g的倍数)有整数解(cx1/g,cy1/g) , 若 c 不是 gcd 的倍数,则其不存在整数解。

  设ExtendedGCD为扩展欧几里得算法,它接受两个整数a,b,返回两个整数x,y。

  若有ax+by=gcd(a,b),则ExtendedGCD(a,b)可求x,y。

 

1.设a, b, c为任意整数。若方程ax+by=c的一组整数解为(x0,y0),则它的任
意整数解都可以写成(x0+kb', y0-ka'),其中a'=a/gcd(a,b),b'=b/gcd(a,b),k取任意整数。

2.设a, b, c为任意整数,g=gcd(a,b),方程ax+by=c的一组解是(x0,y0),则
当c是g的倍数时ax+by=c的一组解是(x0c/g, y0c/g);当c不是g的倍数时无整数解。

 

 

代码示例:

int e_gcd(int a, int b, int &x, int &y){
    if (b == 0){
        x = 1;
        y = 0;
        return a;
    }
    int r = e_gcd(b, a%b, x, y);
    int t = x;
    x = y;
    y = t - (a/b)*y;
    return r;
}

 紫书上的 exgcd

void exgcd(int a, int b, int &d, int &x, int &y){ // d 表示gcd
    if (b == 0) {d = a; x = 1; y = 0; }
    else {exgcd(b, a%b, d, y, x); y -= (a/b)*x; }
}

 

posted @ 2017-11-14 09:39  楼主好菜啊  阅读(250)  评论(0编辑  收藏  举报