標籤:
【POJ 1061】青蛙的約會(擴充歐幾裡得)
| Time Limit: 1000MS |
|
Memory Limit: 10000K |
| Total Submissions: 103473 |
|
Accepted: 20116 |
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
好久沒刷數論了(或者說從來沒真正開始刷過?=。=
是該啃啃了,最後一段時間,努力試試在這方面找點突破口
擴充歐幾裡得板子題,注意把青蛙AB的前後順序弄對就好。
首先讓A始終是靠左(緯度小)的那隻,如果輸入順序不同,強行swap就好
其次,考慮兩青蛙每秒蹦的距離,如果A > B 公式即為(Sa-Sb)*x ≡ Xb-Xa(mod L)
S表示速度 X表示緯度
如果A < B (Sb-Sa)*x ≡ Xa-Xb(mod L)
然後上板子。。
至於擴偶怎麼搞,原理是什麼,左拐ACdream或各大神犇blog
代碼如下:
#include <iostream>#include <cmath>#include <vector>#include <cstdlib>#include <cstdio>#include <cstring>#include <queue>#include <stack>#include <list>#include <algorithm>#include <map>#include <set>#define LL long long#define Pr pair<int,int>#define fread() freopen("in.in","r",stdin)#define fwrite() freopen("out.out","w",stdout)using namespace std;const int INF = 0x3f3f3f3f;const int msz = 10000;const int mod = 1e9+7;const double eps = 1e-8;LL extend_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 = extend_gcd(b,a%b,y,x);y -= a/b*x;return d;}LL mod_reverse(LL a,LL m,LL c){LL x,y,d;d = extend_gcd(a,m,x,y);if(c%d) return -1;x = (x*(c/d))%m;x = (x%(m/d)+m/d)%(m/d);return x;}int main(){//fread();//fwrite();LL x,y,m,n,l;while(~scanf("%lld%lld%lld%lld%lld",&x,&y,&m,&n,&l)){if(x > y){swap(x,y);swap(m,n);}LL ans;if(m < n) ans = mod_reverse(n-m,l,l-y+x);else ans = mod_reverse(m-n,l,y-x);if(ans == -1) puts("Impossible");else printf("%lld\n",ans);}return 0;}
【POJ 1061】青蛙的約會(擴充歐幾裡得)