zoukankan      html  css  js  c++  java
  • POJ1061 青蛙的约会 —— 扩展gcd

    题目链接:https://vjudge.net/problem/POJ-1061

    青蛙的约会
    Time Limit: 1000MS   Memory Limit: 10000K
    Total Submissions: 122217   Accepted: 25907

    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

    Source

    题意:

    一个圆圈长L,A站在x处,B站在y处,两人向同一方向跳,A每步跳的距离为m,B为n,且A、B跳一步的时间相同。问:至少要条多少步,使得他们某一时刻跳到同一个位置?或者不可能?

    题解:

    1.当跳了a步时(a为正时向右跳,a为负时向左跳),A所在位置为:(a*m + x )%L,B所在位置为:(a*n + y)%L  如果此时两者在同一位置,则:(a*m + x )%L = (a*n + y)%L,即: a*m + x + b*L = a*n + y,移项得:a*(m-n) + b*L = y - x。

    2.可知上述式子为二元一次方程,于是可以用扩展欧几里得算法进行求解。

    3.注意,欧几里得算法需要满足 a*x + b*y = c, 其中 a>0 且 b>0。所以上述式子a*(m-n) + b*L = y - x,如果m-n小于0,则不满足条件了,需要交换位置,即:

    a*n + y + b*L = a*m + x,得:a*(n-m) + b*L = x - y。

    代码如下:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <vector>
     6 #include <cmath>
     7 #include <queue>
     8 #include <stack>
     9 #include <map>
    10 #include <string>
    11 #include <set>
    12 using namespace std;
    13 typedef long long LL;
    14 const int INF = 2e9;
    15 const LL LNF = 9e18;
    16 const int mod = 1e9+7;
    17 const int MAXM = 1e5+10;
    18 const int MAXN = 5e5+10;
    19 
    20 LL exgcd(LL a, LL b, LL &x, LL &y)
    21 {
    22     if(a==0 &&b==0) return -1;
    23     if(b==0) {x=1; y=0; return a;}
    24     LL d = exgcd(b,a%b,y,x);
    25     y -= a/b*x;
    26     return d;
    27 }
    28 
    29 int main()
    30 {
    31     LL x, y, n, m, L;
    32     while(scanf("%lld%lld%lld%lld%lld", &x,&y,&m,&n,&L)!=EOF)
    33     {
    34         if(m<n) swap(m,n), swap(x,y);
    35         LL A = m-n, B = L, C = y-x;
    36         LL X, Y;
    37         LL d = exgcd(A, B, X, Y);
    38 
    39         if(C%d)
    40         {
    41             printf("Impossible
    ");
    42             continue;
    43         }
    44 
    45         X *= C/d;
    46         X = (X%(B/d)+(B/d))%(B/d);
    47         printf("%lld
    ", X);
    48     }
    49 }
    View Code
  • 相关阅读:
    python内置模块collections介绍
    Python的set集合详解
    不同 Python 数据类型的搜寻
    Python 分支、循环、条件与枚举
    ssrf爆破mysql
    php反序列化
    thinkphp历史漏洞
    Thinkphp 缓存RCE
    绕WAF文章收集
    mssql手工盲注
  • 原文地址:https://www.cnblogs.com/DOLFAMINGO/p/8371212.html
Copyright © 2011-2022 走看看