通常我们用这个算法是求最大公约数
最简单的代码是
int gcd(int a,int b)
{
return (b > 0) ? gcd(b,a%b) : a;
}
但是递归次数过多也会超时
不如用//因为并查集中find函数也可以递归实现但是呢对于一个时间限制强的就过不去,换成这种非递归就过了
int gcd1(int a,int b)
{
int r;
while(b>0)
{
r = a % b;
a = b;
b = r;
}
return a;
}
在一个就要求不定方程的解了
对于不定方程的解需要明确
对于a,b,gcd(a,b)一定存在 ax + by = gcd(a,b)
我们就是要找这样的根
如何利用一开始的欧几里得公式呢
你想想对于b,a % b,gcd(b,a%b)
是不是也存在 bx + a% b *y = gcd(b,a %b)
又因为gcd(b , a%b) = gcd(a,b)
所以我们找到了等式
则:ax1 + by1 = bx2 + (a mod b) y2;
即:ax1 + by1 = bx2 + (a - [a / b] * b) y2 = ay2 + bx2 - [a / b] * by2;
也就是ax1 + by1 == ay2 + b(x2-[a/b]*y2);
根据恒等定理得:x1=y2; y1=x2-[a/b]*y2;
所以我们想求的x和y要由gcd后x2,y2来决定
而gcd()结束的条件是b = 0
我们不妨设 a>b。
1,显然当 b=0,gcd(a,b)=a。此时 x=1,y=0;
所以在递归的基础上,我们还要进行层层x与y的更新
#include<iostream>
#include<cstdio>
using namespace std;
int x,y,retgcd;
int exe(int a,int b)
{
if(b == 0)
{
x = 1;
y = 0;
return retgcd = a;
}
else
{
exe(b,a % b);
int temp = x;
x = y;
y = temp - (a / b) * y;
}
}
int main()
{
int a,b;
while(cin>>a>>b)
{
exe(a,b);
printf("%d = (%d) * %d + (%d) * %d\n",retgcd,x,a,y,b);
}
return 0;
}