青蛙的约会
Description
Input
Output
Sample Input
1 2 3 4 5
Sample Output
4
题目分析:假设走了t次相遇,则有等式(x+mt)-(y+nt)=pL成立,等价于求解同余方程(n-m)t≡(x-y) (mod L)的最小整数解
(a)对于一般同余方程ax=d mod b,方程有解,则有(a,d)| b ,所以问题第一步判断解的情况
(b)有(n-m)t+pL=x-y,t、p均为未知变量,将问题转化为求解ax+by=d的最小整数x,扩展欧几里得算法:
briefly:扩展欧几里得算法是辗转相除法求gcd的拓展,表现在ax+by=gcd(a,b),函数extended_gcd()不仅能返回gcd(a,b),还能求出gcd的线性系数x,y,具体的操作步骤如下:
①首先化简 ,得到新的ax+by=d,注意此时(a,b)=1
②先求ax+by=1的解x0、y0(解具有唯一性),利用扩展欧几里得算法得到唯一解x0,则ax+by=d的解x=d*x0
③通解X=x+b*k(k为整数)
(c)通过(b)实际上可以得到同余方程的通解,但是题目要求最小整数解,利用min=(X%b+b)%b,X取正取负均满足最小,问题得解代码+部分解释:
#include
#include
#include
#include
#include
#include
#include
#define maxn 1500
using namespace std;
long long x,y;
long long extended_gcd(long long a,long long b,long long &x,long long &y)//扩展欧几里得算法:求等式ax+by=gcd(a,b)中的x,y;返回d=gcd(a,b)
{
if(b==0) {x=1;y=0;return a;} //边界a*1+0*0=gcd(a,0)=a;
long long d=extended_gcd(b,a%b,y,x);
y-=a/b*x;
return d;
}
long long gcd(long long a,long long b)
{
return b==0?a:gcd(b,a%b);
}
int main()
{
//freopen("input.txt","r",stdin);
long long xx,yy,m,n,l;
long a,b,d;
while(cin>>xx>>yy>>m>>n>>l){
a=n-m;
b=l;
d=xx-yy; //ax=d(mod b)
long long res=gcd(a,b);
if(d%res) cout<<"Impossible"<