您的位置:首页 > 其它

扩展欧几里得

2017-08-23 17:22 155 查看
扩展欧几里得算法试求gcd(a,b)的一个非常高效的算法,具体内容是gcd(a,b)=gcd(b,a%b)。它可以再log时间内求出结果。

什么是扩展欧几里得?

考虑一个问题,如果我们知道a和b的最大公约数c,现在需要求出a*x+b*y=c的通解。这该怎么办?

不难看出通解形式一定是

x=x0+(b/c)*t,y=y0-(a/c)*t。那么该如何求出x0和y0?

首先不难看出x=1,y=0这一特解,我们要考虑的是能否通过这一特解推出结果。

根据欧几里得算法,再求gcd(a,b)时已经的出gcd(b,a%b),那么一定有b*x1+(a%b)*y1=c。

对与这一等式可以转化为:b*x1+(a-a/b*b)*y1=c  ==>  a*y1+b(x1-a/b*y1)=c。很明显 x0=y1,y0=x1-(a/b)*y1。

因此可以通过一个递归程序实现,对于每次递归 xn=xn+1,yn=xn+1-(a/b)*yn+1。

#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
const int maxm = 100005;
int e_gcd(int a, int b, int &x, int &y)
{
if (b == 0)
{
x = 1, y = 0;
return a;
}
int ans = e_gcd(b, a%b, x, y);
int temp = x;
x = y;
y = temp - (a / b)*y;
return ans;
}
int main()
{
int n, i, j, k, sum, a, b, x, y;
while (scanf("%d%d", &a, &b) != EOF)
{
k = e_gcd(a, b, x, y);
printf("%d %d %d\n", k, x, y);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: