POJ 1061 青蛙的约会

POJ_1061

    根据题意可以得到(x+k*m)%L==(y+k*n)%L,所以有x+k*m==y+k*n+t*L,移项得L*t-(n-m)*k==x-y,这时未知数有两个,t和k,而我们的目的得到k的一个最小整数解。

    首先我们可以先用拓展欧几里得得到L*t-(n-m)*k=d的一组解,其中d为abs(n-m)和L的最大公约数。接下来,不妨设求得的一个解为k1,如果x-y不能整除d,那么等式L*t-(n-m)*k==x-y是没有整数解的,如果x-y能够整除d,那么L*t-(n-m)*k==x-y的一组整数解中的k就是k1*(x-y)/d。而k的解是以L/d为单位变化的,这样利用k的一个解以及k变化的单位长度就可以求得k的最小非负整数解了。

#include<stdio.h>
#include<string.h>
long long int X, Y, M, N, L;
long long int abs(long long int x)
{
return x < 0 ? -x : x;
}
void gcd(long long int a, long long int b, long long int &d, long long int &x, long long int &y)
{
if(b == 0)
d = a, x = 1, y = 0;
else
{
gcd(b, a % b, d, y, x);
y -= x * (a / b);
}
}
void solve()
{
long long int d, x, y;
gcd(abs(N - M), L, d, x, y);
if(N - M < 0)
x = -x;
if((X - Y) % d == 0)
{
x = (X - Y) / d * x;
x = (x % (L / d) + L / d) % (L / d);
printf("%lld\n", x);
}
else
printf("Impossible\n");
}
int main()
{
while(scanf("%lld%lld%lld%lld%lld", &X, &Y, &M, &N, &L) == 5)
{
solve();
}
return 0;
}


你可能感兴趣的:(poj)