#include
using namespace std;
int exgcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1,y=0;
return a;
}
int x1,y1,gcd;
gcd=exgcd(b,a%b,x1,y1);
x=y1,y=x1-a/b*y1;
return gcd;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int a,b,x,y;
scanf("%d%d",&a,&b);
exgcd(a,b,x,y);
printf("%d %d\n",x,y);
}
return 0;
}
经过数学推理和证明,可以得出x和y是方程的一组可行解,把原来求最大公约数的模板拆开(最大公约数模板跳转),注意b=0的时候y=0只是一种可行解。其他的感觉记住就行(主要是因为不是很懂)
扩展欧几里得算法用来求方程的一组可行解(ai×xi+bi×yi=gcd(ai,bi))
有一个不理解的地方,就是
int x1,y1,gcd;
gcd=exgcd(b,a%b,x1,y1);
x=y1,y=x1-a/b*y1;
return gcd;
这个部分x1,y1没有初始化就直接使用了,为什么这样写?
参考社区其他人的理解,原帖链接:题解
可以绕过我的这个疑问,代码如下:
#include
using namespace std;
void exgcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1,y=0;
}
else
{
exgcd(b,a%b,x,y);
int t=x;
x=y;
y=t-a/b*y;
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int a,b,x,y;
scanf("%d%d",&a,&b);
exgcd(a,b,x,y);
printf("%d %d\n",x,y);
}
return 0;
}
需要注意的是,上面两份代码函数里面有两个引用符号&,表示的是需要传回x和y的地址
使用y总提供的代码好像是最简洁的
#include
using namespace std;
int exgcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1,y=0;
return a;
}
int d=exgcd(b,a%b,y,x);
y-=a/b*x;
return d;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int a,b,x,y;
scanf("%d%d",&a,&b);
exgcd(a,b,x,y);
printf("%d %d\n",x,y);
}
return 0;
}