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米。现在要你求出它们跳了几次以后才会碰面。
我们把这两只青蛙分别叫做青蛙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 }
- POJ 1061 拓展欧几里德算法
- POJ 1061 :拓展欧几里德
- 欧几里德与拓展欧几里德算法
- 欧几里德 和 拓展欧几里德算法
- POJ 1061 青蛙的约会 拓展欧几里德
- poj 2115 拓展欧几里德
- 拓展欧几里德算法
- 欧几里德算法及拓展
- 拓展欧几里德算法
- 拓展欧几里德算法
- POJ 1064 青蛙的约会(拓展欧几里德算法)
- 欧几里德算法和拓展欧几里德算法
- 欧几里德算法及其拓展算法
- POJ 1061 扩展欧几里德算法
- poj 1061 青蛙的约会(拓展欧几里德)
- 拓展欧几里德 (附 POJ 2115)
- poj 2115 C Looooops 拓展欧几里德定理
- POJ 2115 C Looooops(拓展欧几里德)
- 手工命令创建空白android apk
- HDU 3657 Game 网络流--最大独立集
- 分享11个超棒的移动应用开发解决方案
- HDU 1787 欧拉公式
- POJ 1144 Network ---tarjan算法求割点
- POJ 1061 拓展欧几里德算法
- POJ 2115 模线性方程
- mysqldum命令参数
- HDU 3874 树状数组 + 离线处理
- POJ 2155 Matrix ---二维树状数组
- POJ 3067 Japan 树状数组
- HDU 3826 Squarefree number 判断无平方因子的数
- HDU 2521 求数的因子个数
- HDU 2136 找出某数的最大素数因子