zoukankan      html  css  js  c++  java
  • 【洛谷】【扩欧】P1516 青蛙的约会

    【题目描述】

    两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面。它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止。可是它们出发之前忘记了一件很重要的事情,既没有问清楚对方的特征,也没有约定见面的具体位置。不过青蛙们都是很乐观的,它们觉得只要一直朝着某个方向跳下去,总能碰到对方的。但是除非这两只青蛙在同一时间跳到同一点上,不然是永远都不可能碰面的。为了帮助这两只乐观的青蛙,你被要求写一个程序来判断这两只青蛙是否能够碰面,会在什么时候碰面。

    我们把这两只青蛙分别叫做青蛙A和青蛙B,并且规定纬度线上东经0度处为原点,由东往西为正方向,单位长度1米,这样我们就得到了一条首尾相接的数轴。设青蛙A的出发点坐标是x,青蛙B的出发点坐标是y。青蛙A一次能跳m米,青蛙B一次能跳n米,两只青蛙跳一次所花费的时间相同。纬度线总长L米。现在要你求出它们跳了几次以后才会碰面。

    【输入格式】

     输入只包括一行5个整数x,y,m,n,L

    其中0<x≠y < =2000000000,0 < m、n < =2000000000,0 < L < =2100000000。

     【输出格式】

    输出碰面所需要的天数,如果永远不可能碰面则输出一行"Impossible"。

    【算法分析:】

    设最少需要的次数为k,容易得出:

    求一个非负整数k,使得:

    可以看出,问题变成了求不定方程的x的非负最小值

    求出一组x、y,使得ax+by=gcd(a,b):

    ax + by = gcd(a, b)
        = gcd(b, a % b)
        = bx' + (a % b)y'
        = bx' + (a - [a / b] * b)y'
        = bx' + ay' - [a / b] * by'
        = ay' + b(x' - [a / b]y')
        
    ∴x = y', y = x' - [a / b] * y'
    
    终止条件:
    b = 0时:a * 1 + b * 0 = a
    即x = 1, y = 0
    递归求解
    扩展欧几里得

    求出一组ax+by=c的解:

    用扩展欧几里得先求出ax' + by' = gcd(a, b)的一组解, x',  y'及gcd(a, b)的值
    
    若c mod gcd(a, b) ≠ 0
    方程无解(整数范围内)
    
    令:
    c = gcd(a, b) * k
    ∴k = c / gcd(a, b)
    ∴ax + by = c
          = k * gcd(a, b)
    ∴ax + by = akx' + bky'
    根据恒等定理:
        ax = akx', by = bky'
    ∵a != 0 且 b != 0
    ∴x = kx', y = ky'
    ∵k = c / gcd(a, b)
    ∴x = x' * c / gcd(a, b)
      y = y' * c / gcd(a, b)
    不定方程(同余方程)

    使得x非负且最小:

    用扩展欧几里得先求出ax' + by' = gcd(a, b)的一组解, x',  y'及gcd(a, b)的值
    lcm(a, b) = a * b / gcd(a, b)
    
    ax + lcm(a, b) + by - lcm(a, b) = c
    ax + a * b / gcd(a, b) + by - a * b / gcd(a, b) = c
    a(x + b / gcd(a, b)) + b(y - a / gcd(a, b)) = c
    ∴x + 或 - 任意倍数的b / gcd(a, b)均有对应的y的整数解
    
    设 t = b / gcd(a, b)
    x = ((x' * c / gcd(a, b)) % t + t) % t 为方程的最小非负解.
    x非负且最小
    扩欧代码及详解见我的github:
    DEVILK1

    【代码:】

     1 #include<iostream>
     2 #include<cstdio>
     3 using namespace std;
     4 
     5 int x, y, m, n, l;
     6 
     7 int read() {
     8     int x = 0, f = 1; char ch = getchar();
     9     while(ch < '0' || ch > '9') {
    10         if(ch == '-') f = -1;
    11         ch = getchar();
    12     }
    13     while(ch >= '0' && ch <= '9')
    14         x = (x << 1) + (x << 3) + (ch ^ 48),
    15         ch = getchar();
    16     return x * f;
    17 }
    18 
    19 int ex_gcd(int a, int b, int &x, int &y) {
    20     if(b == 0) {
    21         x = 1, y = 0;
    22         return a;
    23     }
    24     int g = ex_gcd(b, a % b, y, x);
    25     y -= a / b * x;
    26     return g;
    27 }
    28 
    29 int main() {
    30     x = read(), y = read();
    31     m = read(), n = read();
    32     l = read();
    33     int a = n - m, c = x - y;
    34     if(a < 0) a = -a, c = -c;
    35     int x0, y0;
    36     int g = ex_gcd(a, l, x0, y0);
    37     if(c % g != 0) {
    38         puts("Impossible");
    39         return 0;
    40     }
    41     int t = l / g;
    42     x0 = ((1LL * x0 * c / g) % t + t) % t;
    43     cout << x0 << endl;
    44 }
  • 相关阅读:
    【转载】 NumPy之:数据类型对象dtype
    在深度学习的视觉VISION领域数据预处理的魔法常数magic constant、黄金数值的复现: mean=[0.485, 0.456, 0.406],std=[0.229, 0.224, 0.225]
    关于Numpy数据类型对象(dtype)使用详解
    【转载】 大端模式和小端模式的区别是什么?
    在使用pytorch官方给出的torchvision中的预训练模型参数时为保证收敛性要求使用原始的数据预处理方式
    【转载】 解决 sudo echo x > 时的 Permission denied错误
    Javascript高级程序设计第二版前三章基本数据等笔记
    冒号课堂§3.4:事件驱动
    理解 JavaScript 闭包
    Browser clientX scrollLeft clientLeft
  • 原文地址:https://www.cnblogs.com/devilk-sjj/p/8999414.html
Copyright © 2011-2022 走看看