基础知识:
1.对于任意的ax+by=c, 如果我们知道有一组解x0, y0; 那么 x1 = x0+kb'(b'=b/gcd(a,b)), y1 = y0-ka'(a'=a/gcd(a,b));
求解ax + by = c 的过程如下:
1.首先我们利用Egcd求出ax+by=g(g = gcd(a,b))的解。 利用此算法我们可以求出三个数g, x, y
2.然后我们判断c%g==0? 如果不等于0, 那么此方程无整数解。如果等于0的时候那么执行第三步
3.利用g, x, y, c我们求出ax+by=c的一组解x0 = x*c/g, y0 = y*c/g;
4.现在我们利用基础知识1可以求解出ax+by=c的任意一组解。当求最小的满足条件的x的时候我们可以利用模运算:
实例: POJ1061
题意是有两只青蛙在赤道上跳, 第一只青蛙的起点是x, 每次跳m米, 第二只从y开始每次跳n米, 赤道长度为l, 问两只青蛙最少几步相遇?
我们可以列出如下方程x+km = y+kn mod(l) => k(m-n) + k1*l = y-x, 代码如下:
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> using namespace std; typedef long long LL; void gcd(LL a, LL b, LL &d, LL &x, LL &y) { if(!b) { d=a; x=1; y=0;} else { gcd(b, a%b, d, y, x); y -= x*(a/b); } } int main() { LL x, y, m, n, l; cin>>x>>y>>m>>n>>l; LL a=m-n, b=l, c=y-x; LL g; gcd(a, b, g, x, y); if(c%g != 0) { cout<<"Impossible"<<endl; return 0; } LL x0 = c/g*x; //x1 = x0+k*b/g LL bg = b/g>0?b/g:-b/g; x0 = (x0%bg+bg)%bg; //这里使用模运算求解最小值 cout<<x0<<endl; return 0; }