POJ 1061
#include<iostream> //#define int unsigned #define unsigned long long using namespace std; struct node { long x; long y; unsigned a; }; node ans; node euclid(unsigned a,unsigned b); unsigned _mod(unsigned a,unsigned b); int main() { //freopen("acm.acm","r",stdin); unsigned x; unsigned y; unsigned m; unsigned n; unsigned l; unsigned a; unsigned b; cin>>x>>y>>m>>n>>l; b = (y - x); a = (m - n); ans = euclid(a,l); if(_mod(b,ans.a) == 0) cout<<_mod(ans.x * (b / ans.a),l / ans.a)<<endl; else cout<<"Impossible"<<endl; } unsigned _mod(unsigned a,unsigned b) { return (a % b + b) % b; } node euclid(unsigned a,unsigned b) { node res; if(b == 0) { res.x = 1; res.y = 0; res.a = a; return res; } else { node temp; temp = euclid(b,_mod(a,b)); res.x = temp.y; res.y = temp.x - (a/b)*temp.y; res.a = temp.a; } return res; } /* 求解ax≡b(mod n)的原理: 对于方程ax≡b(mod n),存在ax + by = gcd(a,b),x,y是整数。而ax≡b(mod n)的解可以由x,y来堆砌。具体做法,见下面的MLES算法。 第一个问题:求解gcd(a,b) 定理一:gcd(a,b) = gcd(b,a mod b) 实现:古老的欧几里德算法 int Euclid(int a,int b) { if(b == 0) return a; else return Euclid(b,mod(a,b)); } 附:取模运算 int mod(int a,int b) { if(a >= 0) return a % b; else return a % b + b; } 第二个问题:求解ax + by = gcd(a,b) 定理二:gcd(b,a mod b) = b * x' + (a mod b) * y' = b * x' + (a - a / b * b) * y' = a * y' + b * (x' - a / b * y') = a * x + b * y 则:x = y' y = x' - a / b * y' 实现: triple Extended_Euclid(int a,int b) { triple result; if(b == 0) { result.d = a; result.x = 1; result.y = 0; } else { triple ee = Extended_Euclid(b,mod(a,b)); result.d = ee.d; result.x = ee.y; result.y = ee.x - (a/b)*ee.y; } return result; } 附:三元组triple的定义 struct triple { int d,x,y; }; 第三个问题:求解ax≡b(mod n) 实现:由x,y堆砌方程的解 int MLES(int a,int b,int n) { triple ee = Extended_Euclid(a,n); if(mod(b,ee.d) == 0) return mod((ee.x * (b / ee.d)),n / ee.d); else return -1; }//返回-1为无解,否则返回的是方程的最小解 说明:ax≡b(mod n)解的个数: 如果ee.d 整除 b 则有ee.d个解; 如果ee.d 不能整除 b 则无解。 */
关注我的公众号,当然,如果你对Java, Scala, Python等技术经验,以及编程日记,感兴趣的话。
技术网站地址: vmfor.com