一:題意 : 該題是poj上稀有的中文提,他說得是,有兩個青蛙在赤道上跳躍,走環路。起始位置分別爲x,y。每次跳躍距離分別爲m,n。赤道長度爲L。兩青蛙跳躍方向與次數相同的情況下,問兩青蛙是否有方法跳躍到同一點。輸出最少跳躍次數。
二:解析
假設兩隻青蛙跳z步後相遇,所以就有 :(x+m*z) - (y+n*z) =k*L(1) (其中看爲一常數)
我們要求的是就是z,且k是個變量,所以我們可以將他們兩看成歐幾里得擴展中的x,y變量。所以我們將(1)式化解成 :z * (m-n)- k * L = y-x 若我們令 m-n=a , L=b ,c=y-x。這可以表達成(歐幾里得形式):x*a+y*b=c,對於該式子求解,我們利用 解二元一次非其次方程組的方法可解,該方法在:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
using namespace std;
typedef long long LL;
LL N,M,X,Y,l;
LL d,xx,yy;
LL exgcd(LL a,LL b,LL &x,LL &y)
{//擴展歐幾里得
if(b==0)
{
x=1;
y=0;
return a;
}
LL res=exgcd(b,a%b,x,y);
LL T=x;
x=y;
y=T-y*(a/b);
return res;
}
int main()
{
while(scanf("%lld%lld%lld%lld%lld",&X,&Y,&M,&N,&l)!=EOF)
{
d=exgcd(N-M,l,xx,yy);
if((X-Y)%d!=0)
printf("Impossible\n");
else
{
LL k=(X-Y)/d;
xx=xx*k;
LL h=l/d;
xx=(xx%h+h)%h; //防止其最小解爲負數
printf("%lld\n",xx);
}
}
return 0;
}