POJ 1061
青蛙的约会,关于扩展欧几里德算法的问题。
欧几里德算法指的是a与b的最大公约数gcd(a,b)与b与a%b的最大公约数gcd(b,a%b)相同。
其扩展形式ax+by=gcd(a,b);又gcd(b,a%b)=gcd(a,b),可进行递归求得x、y的解,递归终止条件为b=0,此时(x,y,gcd(a,b))=(1,0,a)。
对于ax+by=c形式的问题,显然当c%gcd(a,b)==0时,x,y存在整数解。求得ax+by=gcd(a,b)后将解同乘以c/gcd(a,b)得到ax+by=c的一组特解(x',y')。
通解形式为(x'+b/gcd*i,y'-a/gcd*i),i为任意整数。在本题中我们需要找到最小正整数。
#include <iostream>
#include <cstdlib>
using namespace std;
typedef long long LL;
LL Ex_Eulid(LL a, LL b, LL &x, LL &y)
{
if(b==0){x=1,y=0;return a;}
else
{
LL tx, ty, temp;
temp = Ex_Eulid(b, a%b, tx, ty);
x = ty, y = tx - (a / b) * ty;
return temp;
}
}
int main()
{
LL x,y,m,n,L,N,itv,spd,X,Y,gcd;
while(scanf("%lld%lld%lld%lld%lld",&x,&y,&m,&n,&L)!=EOF)
{
spd = abs(m-n);
itv = (m>n)?((x>y)?(L-x+y):(y-x)):((x>y)?(x-y):(L-y+x));
gcd = Ex_Eulid(spd,L,X,Y);
if(itv%gcd==0)
{
N = X*itv/gcd;
L /= gcd;
N = (L+N%L)%L;
printf("%lld\n",N);
}
else printf("Impossible\n");
}
}