欧几里得算法即辗转相除法,相信大家都知道,是这样的:
int gcd(int a,int b)
{
if(b==0) return a;
else return gcd(b,a%b);
}
接下来开始扩展~
裴蜀定理: 若c为gcd(a,b)倍数,则ax+by=c必有解 证明在这里
那要解ax+by=c(c≡0 mod gcd(a,b)) 可以先解 ax+by=gcd(a,b)
不妨设a≥b≥0
1若b=0 x=1,y=0
2若b≠0 ,则
设递推项 bx'+(a%b)y'=gcd(b,a%b)
ax+by=bx'+(a%b)y'
∴x=y',y=x'-(a/b)*y';
各位可以举个例子看看
好,继续 再把解乘c/gcd(a,b)就可以了
易知 若gcd(a,b)=d 则ax≡c(mod b) 在[0,b/d-1]有唯一解 //同余方程和ax+by=c等价
令r=b/gcd(a,b)
所以其最小解 Xmin=(X%r+r)%r
同理可以求出y.
代码: 做*杯赛必备
#include <bits/stdc++.h>
using namespace std;
long long exgcd(long long a,long long b,long long &x,long long &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
long long d=exgcd(b,a%b,x,y);
long long t=x-(a/b)*y;
x=y;
y=t;
return d;
}
int main()
{
long long a,b,c,x,y,gcd,k,r;
cin>>a>>b>>c;
gcd=exgcd(a,b,x,y);
cout<<"gcd="<<gcd<<endl;
if(c%gcd)
{
puts("No solution");
return 0;
}
k=c/gcd;
long long x1=x*k,y1=y*k;
r=b/gcd;
x1=x1%r;
r=a/gcd;
y1=y1%r;
cout<<"("<<x1<<"*"<<a<<")+("<<y1<<"*"<<b<<")="<<c<<endl;
return 0;
}
推荐例题 poj1061青蛙的约会
noip2012同余方程