• 欧几里得算法及扩展欧几里得算法


    1、欧几里得算法:

    欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数。

    基本算法:设a=qb+r,其中a,b,q,r都是整数,则gcd(a,b)=gcd(b,r),即gcd(a,b)=gcd(b,a%b)。

    证明:

             a可以表示成a = kb + r,则r = a mod b

      假设d是a,b的一个公约数,则有

      d|a, d|b,而r = a - kb,因此d|r

      因此d是(b,a mod b)的公约数

      假设d 是(b,a mod b)的公约数,则

      d | b , d |r ,但是a = kb +r

      因此d也是(a,b)的公约数

      因此(a,b)和(b,a mod b)的公约数是一样的,其最大公约数也必然相等,得证

    2、扩展欧几里德算法

    基本算法:对于不完全为 0 的非负整数 a,b,gcd(a,b)表示 a,b 的最大公约数,必然存在整数对 x,y ,使得 gcd(a,b)=ax+by。

    证明:

             设 a>b。

      1,显然当 b=0,gcd(a,b)=a。此时 x=1,y=0;

      2,ab!=0 时

      设 ax1+by1=gcd(a,b);

      bx2+(a mod b)y2=gcd(b,a mod b);

      根据朴素的欧几里德原理有 gcd(a,b)=gcd(b,a mod b);

      则:ax1+by1=bx2+(a mod b)y2;

      即:ax1+by1=bx2+(a-(a/b)*b)y2=ay2+bx2-(a/b)*by2;

      根据恒等定理得:x1=y2; y1=x2-(a/b)*y2;

         这样我们就得到了求解 x1,y1 的方法:x1,y1 的值基于 x2,y2.

       上面的思想是以递归定义的,因为 gcd 不断的递归求解一定会有个时候 b=0,所以递归可以结束。


    3、相关代码实现:

    #include<iostream>
    using namespace std;
    
    int gcd(int a,int b){
    	return b?gcd(b,a%b):a;
    }
    
    int exgcd(int a,int b,int &x,int &y)
    {
        if(b==0)
        {
            x=1;
            y=0;
            return a;
        }
        int r=exgcd(b,a%b,x,y);
        int t=x;
        x=y;
        y=t-a/b*y;
        return r;
    }
    
    int main(){
    	int a,b,x,y;
    	cin>>a>>b;
    	cout<<gcd(a,b)<<endl;	
    	exgcd(a,b,x,y);
    	cout<<x<<" "<<y<<endl;
    	return 0;
    }

    4、简单应用:

    扩展欧几里德算法求解不定方程

    对于不定整数方程pa+qb=c,若 c mod Gcd(p, q)=0,则该方程存在整数解,否则不存在整数解。
      上面已经列出找一个整数解的方法,在找到p * a+q * b = Gcd(p, q)的一组解p0,q0后,p * a+q * b = Gcd(p, q)的其他整数解满足:
      p = p0 + b/Gcd(p, q) * t 
      q = q0 - a/Gcd(p, q) * t(其中t为任意整数)
      至于pa+qb=c的整数解,只需将p * a+q * b = Gcd(p, q)的每个解乘上 c/Gcd(p, q) 即可。

      在找到p * a+q * b = Gcd(a, b)的一组解p0,q0后,应该是得到p * a+q * b = c的一组解p1 = p0*(c/Gcd(a,b)),q1 = q0*(c/Gcd(a,b)),

      p * a+q * b = c的其他整数解满足:

      p = p1 + b/Gcd(a, b) * t
      q = q1 - a/Gcd(a, b) * t(其中t为任意整数)
      p 、q就是p * a+q * b = c的所有整数解。

    EX:用扩展欧几里得算法解不定方程ax+by=c;

    bool linear_equation(int a,int b,int c,int &x,int &y)
    {
        int d=exgcd(a,b,x,y);
        if(c%d)
            return false;
        int k=c/d;
        x*=k; y*=k;    //求得的只是其中一组解
        return true;
    }


  • 相关阅读:
    配置Python3 Pip3环境变量
    超级搜索术-读书笔记
    技术笔记-图片管理器
    Python不错的资料、网站
    输入法9键 VS 26键,哪个更适合?
    超级搜索术-思维导图
    Linux知识-Docker
    Python知识体系-基础知识03-函数/类/模块
    js基础(BOM对象)
    js基础(事件)
  • 原文地址:https://www.cnblogs.com/cnyali/p/4163908.html
Copyright © 2020-2023  润新知