POJ-1061 青蛙的約會(擴充套件歐幾里德)
青蛙的約會
Time Limit: 1000MS | Memory Limit: 10000K |
Total Submissions: 130016 | Accepted: 28506 |
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
題意:
有青蛙A,青蛙B兩隻,他們分別從x,y為起點出發,沿著圓圈的相同方向走,圓的長度為L,青蛙A的速度為m,青蛙B的速度為n,問你需要跳多少次它兩個會相遇。
思路:
設時間為t,青蛙A現在的位置為(x+m*t)% L,青蛙B現在的位置為(y+n*t)% L,他兩個相遇即(x+m*t)% L == (y+n*t) % L
(n-m)*t + k*L = x - y;
a = n-m
b = L;
c = x-y;
滿足a*x+b*y = c表示式,然後通過擴充套件歐幾里德模板求出一組(x,y),然後通過通解找最小正整數x,就是我們要輸出的答案。
x0 = x0 % (b/d) + (b/d);就可以求出最小非負整數解x了!
#include<iostream> #include<cstdio> using namespace std; typedef long long ll; ll gcd(ll a, ll b, ll &x, ll &y) { if(a == 0 && b == 0) return -1; if(b == 0) { x = 1; y = 0; return a; } ll d = gcd(b,a%b,y,x); y -= a / b * x; return d; } int main() { ll x, y, m, n, l; cin >> x >> y >> m >> n >> l; ll a = n-m; ll b = l; ll c = x-y; ll x0, y0; ll d = gcd( a, b, x0, y0); if(c % d) cout << "Impossible" << endl; else { x0 = x0*c/d; y0 = y0*c/d; int t = b / d; if(x0 >= 0) // 求x的最小正整數 x0 = x0 % t; else x0 = x0 % t + t; cout << x0 << endl; } return 0; }