zoukankan      html  css  js  c++  java
  • 欧几里得扩展算法

    欧几里得扩展算法

    首先证明欧几里德算法(即最大公约数算法)

    设有a,b两个数;

    a=k*b+r,r=a%b;

    假设d是a,b的一个公约数,a%d=0,b%d=0;r=a-k*b,因此r%d=0;

    即所有a,b的公约数都是b,a%b的公约数,那么gcd(a,b)=gcd(b,a%b);

    所以当a%b=0时,即a和b的最大公约数就是他们本身;


    算法代码

    int gcd(int a,int b)
    {
        return b==0?a:gcd(b,a%b);
    }
    gcd(a,b)=gcd(b,r0)=gcd(r0,r1)=...=gcd(rn-1,rn)=gcd(rn-1,0)=rn-1.


    接下来讲解欧几里得扩展算法(即求n*a+m*b=gcd(a,b)中的n,m)

    首先m*a+n*b=gcd(a,b);

    当a=k*b+r;r=0时,m=0,n=1;

    当r!=0时,有上述可知m*(k*b+r)+n*b=gcd(a,b)=gcd(b,r);

    假设m1*b+n1*r=gcd(b,r);

    b=k1*r+r1;当r1=0时,则m1,n1已知;

    代入上式 得

    m1*b+n1*r=m*(k*b+r)+n*b;

    m1*b+n1*r=(m*k+n)*b+m*r;

    得 m=n1,n=m1-m*k=m1-n1*a/b;

    由于代码中用了引用所以是y-=x*(a/b),仔细理解一下;

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

    最后总结:

    关于欧几里得算法用于求解整数问题和最大公约数(白书179);

    虽然可以求出一组解但是本质上是有许多解的,比如已知(x,y),所有解为(x+k*b/gcd(a,b),y-k*a/gcd(a,b));

  • 相关阅读:
    音乐商店
    sort函数
    优先队列
    畅通工程 并查集,最小生成树,最短路径
    线段树(segment tree )
    bfs
    完全背包
    【Matlab】向图像域添加噪声/高斯/均匀/伽马/指数/椒盐
    【手帐】Bullet Journal教程
    【Matlab】取整函数:fix/round/floor/ceil
  • 原文地址:https://www.cnblogs.com/zhangteng512/p/2090924.html
Copyright © 2011-2022 走看看