拓展欧几里得算法【Extended Euclidean Algorithm】
一、什么是拓展欧几里得算法?
扩展欧几里德算法是用来在已知a, b求解一组x,y,使它们满足贝祖等式: ax+by = gcd(a, b) =d(解一定存在,根据数论中的相关定理)。扩展欧几里德常用在求解模线性方程及方程组中。(源自:百度百科)
二、递推理解。
对应一个不定式:
ax+by=gcd(a,b)
肯定解是不唯一的,那么我们考虑求一个特解。
我们已知欧几里得算法的小伙伴都知道,欧几里得算法的终止的条件是:a==gcd(a,b)&&b==0的时候。
那么此时有:x===1&&y==0;那么我们是否能够通过逆推的方式得到最初的x,y呢?答案是可行的。
每一步递归的欧几里得算法都会求出一个ans=gcd(b,a%b);
那么我们就已知:
gcd(a,b)=b*x1+(a%b)*y1;①
我们还已知:a%b=[a-(a/b*b)];(这里a==5%%b==2的时候a/b=2)②
将②带入①有:
gcd(a,b)=b*x1+[a-(a/b*b)]*y1;
gcd(a,b)=ay1+b*(x1-a/b*y1);
那么又根据:gcd(a,b)=ax+by;
那么此时就已知:
x=y1;
y=x1-a/b*y1;
那么在算法实现过程中,只要在欧几里得算法的基础上添加一些元素即可。
三、对于问题代码的实现:
#include<stdio.h>
#include<string.h>
using namespace std;
int x,y;
int ex_gcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
int ans=ex_gcd(b,a%b,x,y);
int tmp=x;
x=y;
y=tmp-a/b*y;
return ans;
}
int main()
{
int a,b;
while(~scanf("%d%d",&a,&b))
{
ex_gcd(a,b,x,y);
printf("%d %d\n",x,y);
}
}