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

本文详细介绍了欧几里得算法及其扩展版本,用于求解两个整数的最大公因数和线性方程ax+by=gcd(a,b)的特解。通过递归方式实现算法,并提供了C++代码示例。

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

转载于:https://www.cnblogs.com/pigzhouyb/p/10119692.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值