POJ 1061 拓展欧几里德算法

来源:互联网 发布:成都医疗大数据公司 编辑:程序博客网 时间:2024/06/06 08:27

学习自http://www.cnblogs.com/ka200812/archive/2011/09/02/2164404.html,博主写得太好了,推荐!

青蛙的约会
Time Limit: 1000MS Memory Limit: 10000KTotal Submissions: 77540 Accepted: 13085

Description

两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面。它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止。可是它们出发之前忘记了一件很重要的事情,既没有问清楚对方的特征,也没有约定见面的具体位置。不过青蛙们都是很乐观的,它们觉得只要一直朝着某个方向跳下去,总能碰到对方的。但是除非这两只青蛙在同一时间跳到同一点上,不然是永远都不可能碰面的。为了帮助这两只乐观的青蛙,你被要求写一个程序来判断这两只青蛙是否能够碰面,会在什么时候碰面。
我们把这两只青蛙分别叫做青蛙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 }

 

原创粉丝点击