青蛙的约会(扩展欧几里得模板题(模板已升级))
来源:互联网 发布:linux系统命令 编辑:程序博客网 时间:2024/05/21 17:04
Link:http://poj.org/problem?id=1061
青蛙的约会
Time Limit: 1000MS Memory Limit: 10000KTotal Submissions: 98118 Accepted: 18589
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
Source
浙江
编程思想:依题意,可推出公式为 (x + m * s) - (y + n * s) = k * L(k = 0, 1, 2,...),公式化简,得 (n-m) * s + k * l = x - y。令a= (n-m),x=s,b= l ,y=k,c=x - y,即转化为模板题,判断a * x + b * y = c,是否存在整数解。可用扩张欧几里得求解该线性方程。
下面代码中的扩张欧几里得模板来自:http://blog.csdn.net/zhengnanlee/article/details/11607755
AC code:
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <set>#include <map>#include <queue>#define PI acos(-1.0)#define LINF 1000000000000000000LL#define eps 1e-8#define LL long long#define MAXN 100010 using namespace std;const int INF=0x3f3f3f3f;LL gcd(LL a, LL b){ return b ? gcd(b, a%b) : a;}//find x, y that satisfied the equation ax+by=d, which minimize the {|x|+|y|}. ps:d = gcd(a,b).void exgcd(LL a, LL b, LL &d, LL &x, LL &y){ if (!b) { d = a, x = 1, y = 0; } else { exgcd(b, a %b, d, y, x); y -= x * (a / b); }}//1、先计算Gcd(a, b),若n不能被Gcd(a, b)整除,则方程无整数解;否则,在方程两边同时除以Gcd(a, b),得到新的不定方程a' * x + b' * y = n',此时Gcd(a', b')=1;//2、利用上面所说的欧几里德算法求出方程a' * x + b' * y = 1的一组整数解x0, y0,则n' * x0,n' * y0是方程a' * x + b' * y = n'的一组整数解;//3、根据数论中的相关定理,可得方程a' * x + b' * y = n'的所有整数解为://x = n' * x0 + b' * t//y = n' * y0 - a' * t//(t为整数)bool getans(LL a, LL b, LL c, LL &ans)// ax + by = c 最小整数解{ LL r = gcd(a, b), y0; if (c%r)//no solutions { return false; } a /= r, b /= r, c /= r; exgcd(a, b, r, ans, y0);//至此,上面的说明解决了 LL t = c * ans / b; ans = c * ans - t * b; /*此时方程的所有解为:x = c*ans - b*t, x的最小的可能值是0 令x = 0可求出当x最小时的t的取值,但由于x = 0是可能的最小取值,实际上可能x根本取不到0 那么由计算机的取整除法可知:由 t = c*k1 / b算出的t 代回x = c*ans - b*t中,求出的x可能会小于0,此时令t = t + 1,求出的x必大于0; 如果代回后x仍是大于等于0的,那么不需要再做修正。*/ if (ans < 0) { ans += b; } return true;}LL x,y,m,n,L,a,b,c,ans;bool fg;int main(){while(scanf("%lld%lld%lld%lld%lld",&x,&y,&m,&n,&L)!=EOF){a=n-m;b=L;c=x-y;fg=getans(a,b,c,ans);if(!fg){printf("Impossible\n");}else{printf("%lld\n",ans);}} return 0;}
扩张欧几里得模板升级版:
AC code:
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <vector>#include <string>#include <queue>#include <stack>#include <algorithm>#define PI acos(-1.0)#define LINF 1000000000000000000LL#define eps 1e-8#define LL long long#define MAXN 100010 #define MOD 1000000007using namespace std;const int INF=0x3f3f3f3f;LL exgcd(LL A,LL &x,LL B,LL &y){ LL x1,y1,x0,y0; x0=1;y0=0; x1=0;y1=1; LL r=(A%B+B)%B; LL q=(A-r)/B; x=0;y=1; while(r) { x=x0-q*x1; y=y0-q*y1; x0=x1; y0=y1; x1=x;y1=y; A=B;B=r;r=A%B; q=(A-r)/B; } return B;}LL x,y,m,n,L,a,b,c,ans; int main(){ while(scanf("%lld%lld%lld%lld%lld",&x,&y,&m,&n,&L)!=EOF) { a=n-m; b=L; c=x-y; LL x0,y0,flag=0,x,y,min_x,min_y; if(a<b){flag=a;a=b;b=flag;flag=1;}//默认令a>=b,flag=1说明有交换,则对应的系数x和y最后输出时也要交换后输出 int d=exgcd(a,x0,b,y0);//返回a、b的最大公约数 //求ax+by=c if(c%d!=0)//无解 { printf("Impossible\n");}else{x0=x0*(c/d);//x的一个解 y0=y0*(c/d);//y的一个解 LL t=y0/(a/d),minx=INF,miny=INF; for(int i=t-1;i<=t+1;i++) { //x的所有解是x=x0+b/d*t,y的所有解是:y=y-a/d*t。 x=x0+b/d*i; y=y0-a/d*i; /*if(fabs(x)+fabs(y)<min) { min=fabs(x)+fabs(y); min_x=fabs(x); min_y=fabs(y); }*/ //printf("%d %d\n",x,y); if(x>=0) { minx=min(minx,x);} if(y>=0) { miny=min(miny,y);} } /*if(flag)printf("%lld %lld\n",min_y,min_x); else printf("%lld %lld\n",min_x,min_y);*/ if(flag)printf("%lld\n",miny); else printf("%lld\n",minx); //printf("%lld\n",minx); } } return 0;}
0 0
- 青蛙的约会(扩展欧几里得模板题(模板已升级))
- poj 青蛙的约会 1061 (拓展欧几里得 模板)
- poj 1061 青蛙的约会 (扩展欧几里得模板)
- 青蛙的约会(扩展欧几里得)
- 青蛙的约会(欧几里得扩展)
- poj1061青蛙的约会(扩展欧几里得)
- 青蛙的约会(扩展欧几里得)
- POJ1061青蛙的约会(扩展欧几里得)
- poj1061青蛙的约会(扩展欧几里得)
- POJ1061 青蛙的约会(扩展欧几里得)
- POJ1061:青蛙的约会(扩展欧几里得)
- 青蛙的约会(扩展欧几里得)
- 青蛙的约会(扩展欧几里得)
- [poj1061]: 青蛙的约会(扩展欧几里得)
- 青蛙的约会(扩展欧几里得)
- poj-1061-青蛙约会-扩展的欧几里得算法的模板题
- POJ 1061青蛙的约会(扩展的欧几里得)
- poj1061(青蛙的约会)(欧几里得扩展原理应用)
- 失业皇帝观后感
- The stack size specified is too small, Specify at least 228k
- uiwebview添加到阅读列表
- kvc和kvo的使用情况的了解
- xcode修改代码目录结构出现clang:error:nosuchfileordirectory解决方法
- 青蛙的约会(扩展欧几里得模板题(模板已升级))
- hibernate3第三章之关联映射
- 深入理解PHP原理之错误抑制与内嵌HTML
- ARM处理器寄存器
- Oracle学习笔记20150822分页查询sql语句分类和集合运算
- leetcode263_264:Ugly Number & Ugly Number II
- Cocos2d-x 创建精灵的五种方法
- 腾讯微博分享的时候,无法进行授权。
- django学习(1)编写技巧