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

    原博客:https://www.cnblogs.com/haveyoueverbeen/p/4612753.html

    关于扩展欧几里得算法(Extended Euclidean Algorithm),我是在做青蛙的约会这一经典题目才接触到这个算法的。后面也有关于这一题的AC代码和解题思路。

    内容:已知a, b,求解一组x,y,使它们满足贝祖等式: ax+by =gcd(a, b)

    扩展欧几里得算法,就和它的名字一样是对欧几里得算法的扩展。何为扩展?一是,该算法保留了欧几里得算法的本质,可以求a与b的最大公约数。二是,已知a, b求解二元一次方程ax+by =gcd(a, b)的一组解(x,y)。

    证明:

    假设 a>b,

    (1) b=0 gcd(a,b) = a , ax = a , 则x=1,y=0;(这里我还是推荐不把gcd(a,0)理解成最大公约数,而是一个计算机求出来的值)

    (2) 假设 ax1+by1=gcd(a,b) (方程一) bx2+(a%b)y2=gcd(b,a%b)(方程二);由欧几里得算法gcd(a,b) =gcd(b,a%b) 得到,

    ax1+by1 = bx2+(a%b)y2,即ax1+by1=bx2+(a-a/b*b)y2 ax1+by1=ay2+b(x2-a/b*y2)

    在根据多项式恒等定理(把a,b看成变量),x1=y2; y1=x2-a/b*y2;

    (表面上看,就是已知方程一的一组解,可以得到方程二的一组解,已知方程二的一组解,就可以得到方程一的一组解,但是实际情况是,不可能先知道方程一的解(x1,y1)。)上述思想是递归定义的,不断地利用gcd(a,b) =gcd(b,a%b),到b=0(y的系数为0)时,由(1)的解,根据解之间的关系,最终可以得到方程ax+by =gcd(a, b)的解。

    递归形式代码:

    #include<iostream>
    using namespace std;
    
    int exgcd(int a,int b,int &x,int &y)
    {
         if(b==0)
        {
            x=1;
            y=0;
            return a;
        }
        int gcd=exgcd(b,a%b,x,y);
        int x2=x,y2=y;
        x=y2;
        y=x2-(a/b)*y2;
        return gcd;
    }
    
    int main()
    {
    int x,y,a,b;
    cout<<"请输入a和b:"<<endl;
    cin>>a>>b;
    cout<<"a和b的最大公约数:"<<endl;
    cout<<exgcd(a,b,x,y)<<endl;
    cout<<"ax+by=gcd(a,b) 的一组解是:"<<endl;
    cout<<x<<" "<<y<<endl;
    return 0;
    }

    非递归形式代码:

    #include<iostream>
    using namespace std;
    
    int exgcd(int a,int b,int &x,int &y)
    {
        int x1,y1,x0,y0;
        x0=1; y0=0;
        x1=0; y1=1;
        x=0; y=1;
        int r=a%b;
        int q=(a-r)/b;
        while(r)
        {
            x=x0-q*x1; y=y0-q*y1;
            x0=x1; y0=y1;
            x1=x; y1=y;
            a=b; b=r; r=a%b;
            q=(a-r)/b;
        }
        return b;
    }
    
    int main()
    {
    int x,y,a,b;
    cout<<"请输入a和b:"<<endl;
    cin>>a>>b;
    cout<<"a和b的最大公约数:"<<endl;
    cout<<exgcd(a,b,x,y)<<endl;
    cout<<"ax+by=gcd(a,b) 的一组解是:"<<endl;
    cout<<x<<" "<<y<<endl;
    return 0;
    }

    同样有两点想说明:

    1.扩展欧几里得算法是对欧几里得算法的扩展,可以求出gcd(a,b),好多人都没意识到这一点。

    2.x,y可以用全局变量,参数传递就不用传引用了。

  • 相关阅读:
    [转载]c++转python
    [转载]One-hot编码
    [转载]各种机器学习算法的应用场景
    SVC和SVR
    机器学习-正则化+回归与分类辨析
    C#编译时,提示缺少NuGet包
    C++中 左值和右值的区别
    C++11并发编程实战 免费书籍
    静态库和动态库
    C++中string类
  • 原文地址:https://www.cnblogs.com/kuronekonano/p/11135723.html
Copyright © 2011-2022 走看看