欧几里得及其扩展

欧几里得也就是我们说的辗转相除法,用于求最大公约束(辗转相减法也可以求)。

欧几里得

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

 这是递归的代码,下面来证明

设c==gcd(a,b);  r=a%b;

则 a==x1*c;  b==x2*c;  r==a-x3*b;  (x1,x2,x3均为正整数)

将a,b代入得:r==x1*c-x3*x2*c==(x1-x3*x2)*c;

因此a,b的余数r是gcd(a,b)的倍数;

因此可以得到:c==gcd(b,r);  从而得到gcd(a,b)==gcd(b,r);          

所以当循环一直进行下去直到r==0,所求的数即gcd(a,b);

欧几里得及其扩展

我们知道,对于自然界的正整数...a,b...一定满足ax+by==gcd(a,b);  (解一定存在,根据数论中的相关定理)

(1)...ax+by==gcd(a,b);

(2)...bx1+a%by1==gcd(b,a%b);  (运用欧几里算法)

(3)...gcd(a,b)==gcd(b,a%b);  (欧几里得算法)

(4)...ax+by==bx1+a%b*y1;  (在计算机里a%b==(a-a/b*b))

(5)...ax+by==bx1+ay1-a/b*by1;

(6)...ax+by==ay1+b(x1-a/b)y1;  (合并同类项)

(7)...x=y1,y=x1-a/b*y1;  (结论)

    所以我们知道x,y和方程的下一个状态量(x1,y1)有关,而方程最后一个状态(即gcd(a,b)终点,b==0;)此时:

ax+0==a;  (gcd(a,b)的最终返回值为a)  可以得到一组解{x==1; y==0},根据此解层层上推即可得到最开始的x,y.

struct Euclid
{
    int x,y,gcd;
}AC;//全局变量;
 
int exgcd(int a,int b)
{
    if(b==0)
    {
        AC.x=1;
        AC.y=0;
        return a;
    }
    int ret=exgcd(b,a%b);
    int t=AC.x;
    AC.x=AC.y;
    AC.y=t-a/b*AC.y;
    return ret;
}

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值