青蛙的约会
【题目描述】
有两只青蛙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)。 */