学习自http://www.cnblogs.com/ka200812/archive/2011/09/02/2164404.html,博主写得太好了,推荐!
青蛙的约会
| Time Limit: 1000MS | Memory Limit: 10000K | |
| Total Submissions: 77540 | Accepted: 13085 |
Description
两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面。它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止。可是它们出发之前忘记了一件很重要的事情,既没有问清楚对方的特征,也没有约定见面的具体位置。不过青蛙们都是很乐观的,它们觉得只要一直朝着某个方向跳下去,总能碰到对方的。但是除非这两只青蛙在同一时间跳到同一点上,不然是永远都不可能碰面的。为了帮助这两只乐观的青蛙,你被要求写一个程序来判断这两只青蛙是否能够碰面,会在什么时候碰面。
我们把这两只青蛙分别叫做青蛙A和青蛙B,并且规定纬度线上东经0度处为原点,由东往西为正方向,单位长度1米,这样我们就得到了一条首尾相接的数轴。设青蛙A的出发点坐标是x,青蛙B的出发点坐标是y。青蛙A一次能跳m米,青蛙B一次能跳n米,两只青蛙跳一次所花费的时间相同。纬度线总长L米。现在要你求出它们跳了几次以后才会碰面。
我们把这两只青蛙分别叫做青蛙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
拓展欧几里德算法:对于任意a*x+b*y = gcd(a,b),以下算法可以求出满足该等式的一组解。
View Code
1 int x,y; 2 3 int GCD(int a,int b) 4 { 5 if(!b) 6 { 7 x = 1; y = 0; return a; 8 } 9 int temp,gcd; 10 gcd = GCD(b,a%b); 11 temp = x; 12 x = y; 13 y = x - (a/b)*y; 14 return gcd; 15 }
解析:为什么 b == 0的时候,x=1,y=0呢,因为b=0的话,原式就变成了a*x=gcd(a,0)=a。再考虑为什么y = temp - (a/b)*y,设第一层时等式为a*x+b*y=gcd(a,b),那么第二层就是
b*x1+(a%b)*y1 = gcd(b,a%b);由于gcd(a,b)==gcd(b,a%b),所以有a*x+b*y = b*x1+(a%b)*y1;考虑右边的式子,有b*x1+(a-a/b*b)*y1 = a*y1 + b*(x1-a/b)*y1(通过整数的除法得到);再与左边式子比较,很明显下一层的y1 = 上一层的x, y = x1 - (a/b)*y1. (temp 存的就是 x1的值)。
这样便得到方程的一组解x,y。
对于一般等式a*x + b*y = c;则得到的解为x0 = x*c/gcd, y0 = y*c/gcd。(当c不能整除gcd时,无整数解)。若要得方程的所有整数解,一般的有x = x0 + b/gcd*k, y = y1 - a/gcd*k;k为任意整数。
View Code
1 #include <iostream> 2 #include <cstdio> 3 4 using namespace std; 5 6 __int64 x,y; 7 8 __int64 GCD(__int64 a,__int64 b) 9 { 10 if(!b) 11 { 12 x = 1; 13 y = 0; 14 return a; 15 } 16 __int64 temp,gcd; 17 gcd = GCD(b,a%b); 18 temp = x; 19 x = y; 20 y = temp - (a/b)*y; 21 return gcd; 22 } 23 24 int main() 25 { 26 __int64 A,B,m,n,L; 27 while(~scanf("%I64d%I64d%I64d%I64d%I64d",&A,&B,&m,&n,&L)) 28 { 29 __int64 a = n - m; 30 __int64 b = L; 31 __int64 c = A - B; 32 __int64 gcd = GCD(a,b); 33 if(c%gcd) 34 { 35 printf("Impossible\n"); 36 continue; 37 } 38 x = x*(c/gcd); 39 y = y*(c/gcd); 40 __int64 ans = x*gcd/b; 41 ans = x - ans*b/gcd; 42 if(ans < 0) 43 ans += b/gcd; 44 printf("%I64d\n",ans); 45 } 46 return 0; 47 }
本文探讨了两只青蛙在线上相约见面的问题,利用拓展欧几里德算法判断两者是否能在特定条件下相遇,并提供了解决方案的代码实现。
1496

被折叠的 条评论
为什么被折叠?



