拓展欧几里得定理,一个可以求解关于x,y的不定方程的东西:
a*x+b*y=k*(a,b),(a,b,k∈Z且不为零)
因为辗转相除法中有:(a,b)=(b,a%b),并且回溯条件是b==0成立;
当b==0时,(a,b)可取任意值;
不妨设(a,b)=a,则此时方程存在特解x=k,y=0;
所以我们可以以如下方法递归转化原方程:
已知:b*x'+(a%b)*y'=k*(b,a%b)的解; 求解方程a*x+b*y=k*(a,b).
由辗转相除法可得b*x'+(a%b)*y'=a*x+b*y;
因为a%b等价于a-a/b*b;
所以等式a*y'+b*(x'-a/b*y')=a*x+b*y成立;
故x,y必定存在一组特解,并且满足x=y',y=x'-a/b*y';
以此递归推出原式的解即可。
#include<cstdio>
using namespace std;
int a,b,c,x,y;
int exgcd(int a,int b,int &x,int &y){
if(b==0){
x=c/a,y=0;
//printf("%d*%d+%d*%d=%d\n",a,x,b,y,a);
return a;
}
else{
int rt=exgcd(b,a%b,x,y);
int k=x;
x=y;
y=k-(a/b)*y;
//printf("%d*%d+%d*%d=%d\n",a,x,b,y,a);
return rt;
}
}
int main(){
scanf("%d%d%d",&a,&b,&c);
if(c%exgcd(a,b,x,y)==0){
printf("%d %d\n",x,y);
}else{
printf("non\n");
}
}