1
17
2016
0

POJ1061 -- 青蛙的约会

青蛙的约会

Description

两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面。它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止。可是它们出发之前忘记了一件很重要的事情,既没有问清楚对方的特征,也没有约定见面的具体位置。不过青蛙们都是很乐观的,它们觉得只要一直朝着某个方向跳下去,总能碰到对方的。但是除非这两只青蛙在同一时间跳到同一点上,不然是永远都不可能碰面的。为了帮助这两只乐观的青蛙,你被要求写一个程序来判断这两只青蛙是否能够碰面,会在什么时候碰面。 
我们把这两只青蛙分别叫做青蛙A和青蛙B,并且规定纬度线上东经0度处为原点,由东往西为正方向,单位长度1米,这样我们就得到了一条首尾相接的数轴。设青蛙A的出发点坐标是x,青蛙B的出发点坐标是y。青蛙A一次能跳m米,青蛙B一次能跳n米,两只青蛙跳一次所花费的时间相同。纬度线总长L米。现在要你求出它们跳了几次以后才会碰面。 

Input

输入只包括一行5个整数x,y,m,n,L,其中x≠y < 2000000000,0 < m、n < 2000000000,0 < L < 2100000000。

Output

输出碰面所需要的跳跃次数,如果永远不可能碰面则输出一行"Impossible"

Sample Input

1 2 3 4 5

Sample Output

4

Source

 

拓展欧几里得经典题目

该题即为求满足同余方程 x + mt ≡ y + nt (mod L)的最小非负整数解

所以 x + mt - (y + nt) = pL

   (x - y) - (n - m)t = pL

设 A = n - m, B = x - y

则 本题即为

求 At ≡ B (mod L)或At - pL = B 的解

用extend_gcd()求出即可(extend_gcd详见五指山题解

 

贴出代码

#include <cstdio>
typedef long long LL;
LL x, y, m, n, L;
LL A, B, t, p;
LL gcd(const LL &a, const LL &b) {
	return b ? gcd(b, a % b) : a;
}
void extend_gcd(const LL &a, const LL &b, LL &x, LL &y) {
	if (!b) {
		x = 1;
		y = 0;
		return;
	}
	else {
		LL tmp;
		extend_gcd(b, a % b, tmp, x);
		y = tmp - a / b * x;
	}
}
int main()
{
    scanf("%lld%lld%lld%lld%lld", &x, &y, &m, &n, &L);
	x %= L, y %= L, m %= L, n %= L; 
	//本题即为求不定方程 x + mt - (y + nt) = Lp 中t的最小非负整数解
	// (n - m) t ≡x - y (mod L)  ---->  At - Lp = B
	A = n - m, B = x - y;
	if (A < 0) A += L;
	if (B < 0) B += L;
	LL g = gcd(A, L);
	if (B % g) {
		printf("Impossible\n");
		return 0;
	}
	A /= g, B /= g, L /= g;
	extend_gcd(A, L, t, p);
	t %= L; if (t < 0) t += L;
	t = t * B % L;
	printf("%lld\n", t); 
} 

Ps:注意到x, y, m, n的取值范围,本题应开long long

Category: POJ | Tags: POJ 数论 拓展欧几里得 | Read Count: 498

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com