• POJ 1061 青蛙的约会


    题意:有两只青蛙,在L那么长的环上,起点分别为x, y,一次跳跃的长度分别为m,n,问几次跳跃后他们能相遇,如不能相遇输出"Impossible"。

    解法:同余问题+扩展欧几里得。从题意容易推出以下式子:

    设跳跃次数为t,mt + x ≡ nt + y (mod L) (1)。

    根据同余的性质:当a ≡ b (mod c)时,(a - b) % c = 0。

    则式(1)转化成(m - n)t + x - y = pL(p ∈ N)。

    问题变为解二元一次方程ax + by = c最小可行解问题。

    解决这类问题的算法是扩展欧几里得算法:对于不完全为0的非负整数a,b,gcd(a, b)表示a,b的最大公约数,必然存在整数对x,y,使得gcd(a,b) = ax + by。

    对于本题当c不能整除gcd(a, b)的时候说明无解,应输出"Impossible"。

    代码如下:

    int exgcd(LL a, LL b, LL &x, LL &y)
    {
        if(b == 0)
        {
            x = 1;
            y = 0;
            return a;
        }
        int r = exgcd(b, a % b, x, y);
        int t = x;
        x = y;
        y = t - a / b * y;
        return r;
    }
    

    证明:当b = 0时,gcd(a, b) = a,所以x = 1, y = 0。当b <> 0时,ax + by = gcd(a, b),根据欧几里得算法(辗转相除法),令a = b, b = a % b,则新等式为bx1 + (a - [a / b] * b)y1 = gcd(b, a % b),整理得ay1 + b(x1 - [a / b]y1) = gcd(b, a % b),因为gcd(a, b) = gcd(b, a % b),所以x = y1, y = x1 - [a / b] * y1,通过递归实现。(参考自百度百科

    当c能整除gcd(a, b)时,通过扩展欧几里得算法求出ax + by = gcd(a, b)的解X时,ax + by = c的最小解则为X * (c / gcd(a, b)),由于X可能为负数,所以最终答案应为(X % gcd(a, b) + gcd(a, b)) % gcd(a, b)。

    代码:

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<string>
    #include<string.h>
    #include<math.h>
    #include<limits.h>
    #include<time.h>
    #include<stdlib.h>
    #include<map>
    #include<queue>
    #include<set>
    #include<stack>
    #include<vector>
    #define LL long long
    using namespace std;
    LL exgcd(LL a, LL b, LL &x, LL &y)
    {
        if(b == 0)
        {
            x = 1;
            y = 0;
            return a;
        }
        LL r = exgcd(b, a % b, x, y);
        LL t = x;
        x = y;
        y = t - a / b * y;
        return r;
    }
    int main()
    {
        LL x, y, m, n, l;
        while(~scanf("%lld%lld%lld%lld%lld", &x, &y, &m, &n, &l))
        {
            LL X, Y;
            LL a = n - m, b = l, c = x - y;
            LL r = exgcd(a, b, X, Y);
            if(c % r != 0)
            {
                puts("Impossible");
                continue;
            }
            X *= c / r;
            LL R = b / r;
            LL ans = (X % R + R) % R;
            cout << ans << endl;
        }
        return 0;
    }
    

      

  • 相关阅读:
    软件工程网络15结对编程作业(201521123111 陈伟泽)
    软件工程网络15个人阅读作业2(201521123111 陈伟泽)
    软件工程网络15个人阅读作业1(201521123111 陈伟泽)
    Java课程设计——猜数游戏(201521123111 陈伟泽)
    java课程设计--猜数字(团队博客)
    201521123111《Java程序设计》第14周学习总结
    201521123111《Java程序设计》第13周学习总结
    个人作业5
    ,软工第四次作业
    第三次作业
  • 原文地址:https://www.cnblogs.com/Apro/p/4385223.html
Copyright © 2020-2023  润新知