码迷,mamicode.com
首页 > 编程语言 > 详细

欧几里得与扩展欧几里得算法

时间:2018-12-14 17:24:50      阅读:206      评论:0      收藏:0      [点我收藏+]

标签:class   理解   int   oid   一个   cpp   简单   span   通过   

欧几里得算法:最大公因数\((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>

欧几里得与扩展欧几里得算法

标签:class   理解   int   oid   一个   cpp   简单   span   通过   

原文地址:https://www.cnblogs.com/pigzhouyb/p/10119692.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!