Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 115219 | Accepted: 23709 |
Description
我們把這兩隻青蛙分別叫做青蛙A和青蛙B,並且規定緯度線上東經0度處爲原點,由東往西爲正方向,單位長度1米,這樣我們就得到了一條首尾相接的數軸。設青蛙A的出發點座標是x,青蛙B的出發點座標是y。青蛙A一次能跳m米,青蛙B一次能跳n米,兩隻青蛙跳一次所花費的時間相同。緯度線總長L米。現在要你求出它們跳了幾次以後纔會碰面。
Input
Output
Sample Input
1 2 3 4 5
Sample Output
4
Source
題解
根據題意可以列出 (s+k*m)%L=(e+k*n)%L,k爲步數,
於是(s+k*m+L*y)%L=(e+kn)%L
然後s+k*m+L*y=e+k*n
移項轉換一下得,(m-n)*k+L*y=e-s
用x代替k 於是有(m-k)*x+l*y=e-s 這就類似於ax+by=c的形式了
擴展歐幾里德可以求出一組解,xo,yo;
ax+by=gcd(a,b);
求x的最小正整數解
求出來x可能是負的,但是a(x+bn)+b(y-an)=gcd(a,b);
那麼xo=x+bn和yo=y-an都能是該方程的解
那麼最小的正x則爲(x%b+b)%b;
//此題要用long long不然過不了
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
ll x,y;
ll gcd(ll x,ll y){
return y?gcd(y,x%y):x;
}
void exgcd(ll a,ll b){
if(b==0){x=1;y=0;}
else{
exgcd(b,a%b);
ll t=x;
x=y;
y=t-(a/b)*y;
}
}
int main(){
ll s,e,m,n,l;
scanf("%lld%lld%lld%lld%lld",&s,&e,&m,&n,&l);
ll a=m-n,b=l,c=e-s;
exgcd(a,b);
ll t=gcd(a,b);
if(c%t!=0)
printf("Impossible\n");
else {
x=x*c/t;
printf("%lld\n",(x%b+b)%b);
}
return 0;
}