poj 1061 青蛙的约会 (扩展欧几里得模板)
Posted Ritchie丶
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj 1061 青蛙的约会 (扩展欧几里得模板)相关的知识,希望对你有一定的参考价值。
Description
我们把这两只青蛙分别叫做青蛙A和青蛙B,并且规定纬度线上东经0度处为原点,由东往西为正方向,单位长度1米,这样我们就得到了一条首尾相接的数轴。设青蛙A的出发点坐标是x,青蛙B的出发点坐标是y。青蛙A一次能跳m米,青蛙B一次能跳n米,两只青蛙跳一次所花费的时间相同。纬度线总长L米。现在要你求出它们跳了几次以后才会碰面。
Input
Output
Sample Input
1 2 3 4 5
Sample Output
4
公青蛙一开始在x位置,母青蛙在y位置。公青蛙每次跳m米,母青蛙每次跳n米,并且都是向右跳的。地球经线长度是L,然后地球是圆的,也就是说,跳到L、L+1、L+2……其实就是跳到0、1、2。 公青蛙想追母青蛙,问多少次后它们能跳到一起。如果它们永远不能相遇,就输出Impossible
就是求一个k,使x + k*m ≡ y + k*n (mod L) ,然后对方程化简,就变成(n-m) * k ≡ x-y (mod L)。然后这个方程其实就等价于(n-m)*k + L*s = x-y。这就是ax + by = c求整数x的模型。
要求ax + by = c的整数x解。(n-m)*t+L*S=x-y。首先,设d = gcd(a, b),方程两边除以d得到a/d * x + b/d * y = c/d,a是整除d的,b也是整除d的,而x、y都是整数解,所以要求c/d也是整数。如果c不整除d,当然就是Impossible。我们能求出ax0+by0=d的解x0和y0,那么两边乘以c/d即a(c/d * x0) + b(c/d * y0) = c,就可以得到原来方程的解x = (c/d * x0),y = (c/d * y0)。
所以x0 * (c / d)是最小的解,但有可能是负数。
因为a * ( x0 *(c / d) + b*n) + b * (y0 * (c / d ) – a*n) = c; (n是自然数)
所以解为 (x0 * (c / d) % b + b) % b;
#include <iostream> using namespace std; typedef long long ll; void gcd(ll a,ll b,ll &d,ll &x,ll &y) { if(!b) {d=a;x=1;y=0;} else {gcd(b,a%b,d,y,x);y-=x*(a/b);} } int main() { ll x,y,m,n,L,X,Y,d,r; while(cin>>x>>y>>m>>n>>L) { gcd(n-m,L,d,X,Y); //d指的是每次可以让x-y的差距改变d个 r=L/d; //走r次走整数个L 走回原点 //因为可能结果是负数 根据等式 +b/d if((x-y)%d) //无法改变为0 cout<<"Impossible"<<endl; else cout<<((x-y)/d*X%r+r)%r<<endl; } return 0; }
以上是关于poj 1061 青蛙的约会 (扩展欧几里得模板)的主要内容,如果未能解决你的问题,请参考以下文章