P1516题解

P1516 青蛙的约会

题意:

有两只青蛙,在一个长为 \(l\) 的环上朝同一方向跳。它们刚开始分别位于环上的位置 \(x\) 和位置 \(y\),每秒分别能跳 \(m\)\(n\) 步。求最少跳多少次,它们能在同一时间到达同一位置。

分析:

我们设它们跳 \(k\) 次,则题目是要我们求同余方程 \(m+kx\equiv n+ky(\mod l)\) 的最小正整数解。

转化为不定方程:\((m-n)k+(x-y)=pl\)(其中 \(p\) 为 正整数)。

移项,得:\((n-m)k+pl=(x-y)\)

我们设 \(a=n-m,b=l,c=(x-y),d=gcd(a,b)\),则换元后方程为 \(ak+bp=c\)。若 \(c\nmid d\),根据扩展欧几里得算法,此时无解。否则我们算出 \(ak+bp=d\) 的解为 \(x_0,y_0\),得到 \(ax_0+by_0=d\),两边同乘 \(\dfrac{c}{d}\),得:\(a\dfrac{cx_0}{d}+b\dfrac{cy_0}{d}=c\),因此 \(\dfrac{cx_0}{d}\) 就是我们要求得解。

但是这样还不够,因为求最大公约数只对非负整数有意义,因此若 \(a<0\),我们要让 \(a,c\) 同时取相反数得到答案。

Code:

/*
user:xcj
time:2022.4.22
*/
#include <bits/stdc++.h>
#define int long long
using namespace std;

int n, m, a, b, d, x, y, l;

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

signed main(){
    scanf("%lld %lld %lld %lld %lld", &x, &y, &m, &n, &l), a = n - m, b = x - y;
    if (a < 0) a = -a, b = -b;
    d = exgcd(a, l, x, y);
    if (b % d) puts("Impossible");
    else printf("%lld\n", (b / d * x % (l / d) + l / d) % (l / d));
    return 0;
}
posted @ 2022-04-22 14:42  leoair  阅读(42)  评论(0)    收藏  举报