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

    ## 欧几里得算法:最大公因数$(gcd)$ 该算法基于: $gcd(a,b)=gcd(b,a$%$b)$

    证明:
    \(a\) % \(b = r\),

    \(a = k * b + r,\)

    因此\(r = a - k * b\)

    \(d\)\(a,b\)的公约数,那么\(d|a, d|b,\)

    \(a - k * b\) 能被\(d\)整除,即\(d|r\),即\(d|(a\) % \(b)\)

    因此\(d\)\(b\)\((a\) %\(b)\)的公约数,

    因此\(a,b\) 的公约数和\(b, (a\)%\(b)\)的公约数是同一个数,

    得出\(gcd(a,b)=gcd(b,a\)%\(b)\)

    同时知道\(gcd(a,0)=a\)

    因此递归求解即可:

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

    对于这个简单的gcd,背结论不求甚解我觉得是可以dei


    扩展欧几里得算法\((exgcd)\)

    对于一类形如\(ax+by=gcd(a,b)\)的方程求解其x,y的一组解:

    通过辗转法,可得\(bx+y(a\)%\(b)=gcd(b,a\)%\(b)\)

    用除法代替取模,则:\(bx+y(a-[a/b]*b)=gcd(b,a\)%\(b)\)(这一步仅仅是原方程的变形)

    根据上述欧几里得算法可得,\(gcd(a,b)=gcd(b,a\)%\(b)\)

    因此\(ax+by=bx'+y'(a-[a/b]*b)\)

    通过乘法分配律和结合律的运算可得:$$ax+by=ay'+b(x'-[a/b]*y')$$

    其中,\(x'\)\(y'\)是方程\(bx+y(a-[a/b]*b)=gcd(b,a\%b)\)的解,用来借助这个已经求得的x'和y'结合已知的a和b推得现在的解\(x,y.\)其中\(a\)\(b\)不变。我们可以通过递归来求。

    递归的边界:
    \(ax+by=gcd(a,0)\)时,即\(b=0\)时,\(x=1\ y=0\).显而易见。

    故代码很好理解了吧:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    int x,y;
    int exgcd(int a,int b)
    {
    	if (b==0) 
    	{ 
    	    x=1; 
    		y=0; 
    		return a; 
    	}
    	int n=exgcd(b,a%b);
    	int t=x;
    	x=y; 
    	y=t-a/b*y;
    	return n;
    }
    int main(void)
    {
    	int a,b;
    	cin>>a>>b;
    	cout<<exgcd(a,b)<<endl;//这里输出最大公约数
    	cout<<x<<' '<<y<<endl;//这个输出方程ax+by=gcd(a,b)的解
    	return 0;
    }
    

    <\font>

  • 相关阅读:
    第十二周助教总结
    第十一周助教总结
    记一次数据库mysql与tidb查询时的区别
    括号校验-Java
    (四)栈和队列的应用
    (三)栈和队列的链式存储结构
    (二)栈和队列的顺序存储结构
    windows开放服务可以远程和被访问(两台电脑可以互相访问)
    (一)栈和队列的基本概念
    (一)数据结构基本概念、存储结构、复杂度
  • 原文地址:https://www.cnblogs.com/pigzhouyb/p/10119692.html
Copyright © 2011-2022 走看看