1. 程式人生 > >POJ 1061 青蛙的約會(拓展歐幾裏得算法求解模線性方程組詳解)

POJ 1061 青蛙的約會(拓展歐幾裏得算法求解模線性方程組詳解)

scrip 坐標 出發點 開心 以及 NPU tdi 青蛙的約會 方程組

題目鏈接:

BZOJ:

https://www.lydsy.com/JudgeOnline/problem.php?id=1477

POJ:

https://cn.vjudge.net/problem/POJ-1061

題目描述:

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

關於如何使用拓展歐幾裏得算法求解模線性方程組的證明請參考另一篇博客:

 1 /*
 2 題意描述
 3 計算滿足(x+km)(mod l)=(y+kn)(mod l) 的k的最小正整數
 4 
 5 解題思路
 6 使用拓展歐幾裏得算法求解模線性方程組
 7 由題知,(x+km)≡(y+kn)(mod l) ,由它的充要條件可得
8 (x+km)-(y+kn)=tl(其中t屬於整數),整理可得 9 k(m-n)-tl=y-x 10 另a=m-n,b=-l,c=y-x 11 可得ak+bl=c,即二元一次方程,利用拓展歐幾裏得算法求得 12 a和b的最大公約數d以及滿足方程的一組解(k0,t0) 13 進而判斷是否有整數解,有整數解後求出最小正整數解 14 */ 15 #include<cstdio> 16 typedef long long LL; 17 18 void extgcd(LL a, LL b, LL &d, LL &k0, LL &t0);
19 20 int main() 21 { 22 LL x,y,m,n,l,a,b,c,d,k0,t0,k,t; 23 while(scanf("%lld%lld%lld%lld%lld",&x,&y,&m,&n,&l) != EOF){ 24 a=m-n; 25 b=l; 26 c=y-x; 27 if(a < 0){ 28 a = -a; 29 c = -c; 30 } 31 extgcd(a,b,d,k0,t0); 32 if(c%d != 0) 33 printf("Impossible\n"); 34 else 35 { 36 k=k0*c/d; 37 l=l/d; 38 if(k >= 0) 39 k %= l; 40 else 41 k = k%l + l; 42 printf("%lld\n",k); 43 } 44 } 45 return 0; 46 } 47 48 void extgcd(LL a, LL b, LL &d, LL &k0, LL &t0) 49 { 50 if(b == 0){ 51 d=a;k0=1;t0=0; 52 } 53 else{ 54 extgcd(b,a%b,d,t0,k0); 55 t0 -= k0*(a/b); 56 } 57 }

POJ 1061 青蛙的約會(拓展歐幾裏得算法求解模線性方程組詳解)