青蛙的约会

【题目描述】

有两只青蛙A、B,规定东经0度为原点,自东向西为正方向,单位长度为1米,由此可得一条首尾相接的纬度线。

设青蛙A的出发点坐标为X,青蛙B的出发点坐标为Y,青蛙A一次跳跃的长度为m米,青蛙B一次跳跃的长度为n米,两只青蛙跳跃一次所耗费的时间相同,纬度线总长度为L米。

现询问两只青蛙跳跃几次之后才能够相遇。

【输入描述】

输入五个整数X、Y、m、n、L(X ≠ Y,X,Y < 2000000000,0 < m,n < 2000000000,0 < L < 2100000000)。

【输出描述】

输出一个整数,表示答案,如果两只青蛙不可能相遇,输出“Impossible”。

【输入样例】

1 2 3 4 5

【输出样例】

4

源代码:

#include<cstdio>
#define LL long long //这个数据坑啊。
LL X,Y;
LL GCD(LL t1,LL t2)
{
    return t2?GCD(t2,t1%t2):t1;
}
void ExGCD(LL t1,LL t2)
{
    if (!t2)
    {
        X=1;
        Y=0;
    }
    else
    {
        ExGCD(t2,t1%t2);
        LL t=X;
        X=Y;
        Y=t-t1/t2*Y;
    }
}
int main()
{
    LL A,B,C,D,m,n,L;
    while (~scanf("%lld%lld%lld%lld%lld",&X,&Y,&m,&n,&L))
    {
        A=n-m;
        B=L;
        C=X-Y;
        D=GCD(A,B);
        if (C%D) //无法推得一般解。
        {
            printf("Impossible\n");
            return 0;
        }
        A/=D;
        B/=D;
        C/=D;
        ExGCD(A,B);
        X=((C*X)%B+B)%B; //这玄乎了,详见下。
        if (!X)
          X+=B; //使其成为正整数。
        printf("%lld\n",X);
    }
    return 0;
}

/*
    设共跳了W次,青蛙A的坐标为(X+mW),青蛙B的坐标为(Y+nW)。
    若能相遇,则有:(X+mW)-(Y+nW)=LP,其中,P为整数,转化一下:
        (n-m)W+LP=X-Y
    设A=n-m、B=L、c=X-Y、W=x、P=y,便能得到形如Ax+By=C的一个式子。
    利用拓展欧几里得算出一组特解后,便能依据性质求出最小解。
就那么一点卡了我一天,还是太弱了T_T。
对于一组任意解(x,y),可知(x-B/D,y+A/D),那么要令x最小,就是不断地减(B/D),就是一个mod。
最终推得x(min)=x*(C/D)%(C/B)。
*/
posted @ 2016-10-26 18:51  前前前世。  阅读(159)  评论(0编辑  收藏  举报