就像之前说的,接触到扩展欧几里得算法,是由于做到了这一题SWUST OJ 青蛙的约会之二(0481) http://www.cnblogs.com/haveyoueverbeen/p/4483218.html (查看题目信息可以戳上面的地址)
解题思路:
设输出结果为 s,则(m*s+x)-(n*s+y)= kl (k∈Z),即(n-m)*s + kl = x-y,设 a=n-m,b=l,c=x-y,即as
+bk=c (ax+by=c),求最小正整数x,然后用扩展欧几里得算法,得到一组解x0 y0。
查得x和y 的通解是:
x=x0+bt; y=y0-at; t∈z;
若求得 x0>=0 则 x0%b 就是题目要求的解;
若求得 x0<0 则 x0%b 为最接近题目要求的解的负数解,所以(x0%b)+b即为题目要求的解。
由于x0>=0时,x0%b=(x0%b)%b。
综上,解就是x0%b)%b。
下面贴上代码:
1 #include<iostream> 2 using namespace std; 3 4 long long int exgcd(long long int a,long long int b,long long int &x,long long int &y) 5 { 6 if(b==0) 7 { 8 x=1; 9 y=0; 10 return a; 11 } 12 long long int gcd=exgcd(b,a%b,x,y); 13 long long int x2=x,y2=y; 14 x=y2; 15 y=x2-(a/b)*y2; 16 return gcd; 17 } 18 19 int main() 20 { 21 long long int x,y,n,m,l,a,b,c,gcd; 22 while(cin>>x>>y>>m>>n>>l) 23 { 24 a=n-m; 25 b=l; 26 c=x-y; 27 gcd=exgcd(a,b,x,y); 28 if(c%gcd!=0) 29 cout<<"Impossible"<<endl; 30 else 31 { 32 c/=gcd; 33 x*=c; 34 x=(x%b+b)%b; 35 cout<<x<<endl; 36 } 37 } 38 return 0; 39 }
时间: 2024-09-30 07:49:13