不定方程(Exgcd)

求解不定方程$ax+by=gcd(a,b)$;

方法:Exgcd

首先 gcd(a,b)=gcd(b,a%b);
因为 gcd(a,b)=ax1+by1
那么 gcd(b,a%b)=bx2+(a%b)y2
有因为 a%b=a-(a/b)*b
所以 ax1+by1=bx2+(a-(a/b)*b)y2
那么 ax1+by1=ay2+b(x2-(a/b)*y2);
根据系数之间的一一对应关系 x1=y2,y1=x2-(a/b)y2;
当递归到gcd(a,0)=a时,我们得到x=1,y=0,然后return ;
由此递归下去,即可得到该不定方程的一组解
对于通解:
假设x0,y0是当前解除的一组解
通解 x=x0+b/gcd(a,b)*k,y=y0+a/gcd(a,b)*k; (k为任意整数)
然后将x,y代入原方程即可验证。
AC Code:
#include<cstdio>
using namespace std;
int x,y;
int exgcd(int a,int b){
if(!b){x=1,y=0;return a;}
int d=exgcd(b,a%b),t=x;
x=y,y=t-(a/b)*y;
return d;
}
int main(){
int a,b;
scanf("%d%d",&a,&b);
exgcd(a,b);
printf("%d %d",x,y);
return 0;
}
那么,现在来考虑不定方程ax+by=c的解
if(c%gcd(a,b)) 无解
else 先利用ax+by=gcd(a,b) 求出一组解x0,y0
令d=gcd(a,b);
代入得ax+by=d ①
①式的左右两边均乘上c/d 得
a(c/d*x0)+b(c/d*y0)=c;
于是现在我们便得到一组解
x1=x0*c/d,y1=y0*c/d
求最小整数解?
就是把x1减小到不能减小为止,因为c、d都是定制,于是考虑把x0减小到不能减小为止
设x0减小x,方程左边减小x*c/d*a,为了保证等式成立,y0应该增加的y值应该满足 y*c/d*b=x*c/d*a;
于是x/y=(b/d)/(a/d);
我们令x0不断减x(x=b/d),直到0<=x1<x,此时的x1即为最小的整数解
我们可以令x1=x0%x,就可以算出x1了
如果x0<0?
那么让x1+x就可以得到正数了
如果x<0?
x=abs(x);
以上就是全部的不定方程的解法了(累死我了。。。)
参考文献:https://www.cnblogs.com/bztMinamoto/p/9321594.html

猜你喜欢

转载自www.cnblogs.com/RisingGods/p/9497928.html