问题描述:
数轴为首尾相接,青蛙A和青蛙B同时开始往正方向跳。A从x开始,每次跳m个单位长度;B从y开始,每次跳n个单位长度。数轴总长为L。求它们跳了几次后能够相遇。
要求:输入一行五个整数,x,y,m,n,L, 其中x!=y,输出一行一个数,表示碰面所需要的跳跃次数,如果永远不可能碰面,则输出一行Impossible.
分析:
设t为跳跃次数,p为A和B跳跃圈数之差,则有下式:
(x+m*t)-(y+n*t)=p*L (1)
(n-m)*t+L*p=x-y (2)
记 a=n-m,b=L,d=x-y,c=GCD(a,b) 则:
a*t+b*p=d (3)
求t的最小整数解。
步骤:
step1:
利用扩展欧几里得算法解a*t+b*p=c的一组最小解(t0.p0)
step2:
若d不能整除c,则无解;
若d能整除c:
(3)式两边同乘d/c得(3)式的一个解为(t0*d/c,p0*d/c)
(但有可能是负数)
由于a*(t0*(d/c)+b*n)+b*(p0*(d/c)-a*n)=d, n为自然数
所以最小非负解为(t0*(d/c)%b+b)%b!!!!!!!!!
代码:
#include<iostream>
using namespace std;
int extended_gcd(int a,int b,int &x,int &y)
{
int ret,tmp;
if(!b)
{
x=1;y=0;
return a;
}
ret=extended_gcd(b,a%b,x,y);
tmp=x;
x=y;
y=tmp-a/b*y;
return ret;
}
int x,y,m,n,L;//题中所给已知量
int gcd;
int x0,y0;//a*x+b*y=c的一组解
int main()
{
cin>>x>>y>>m>>n>>L;
gcd=extended_gcd(n-m,L,x0,y0);
if((x-y)%gcd!=0)
cout<<"Impossible"<<endl;
else
cout<<((long long)x0*(x-y)/gcd%L+L)%L<<endl;
return 0;
}