poj1061 青蛙的约会(扩展欧几里得算法)

题目链接:poj1061 青蛙的约会

青蛙A \(t\) 次跳跃后的坐标为 \((x+mt)\mod L\)

青蛙B \(t\) 次跳跃后的坐标为 \((y+nt)\mod L\)

碰面所需跳跃次数,即求方程

\[x+mt\equiv y+nt(\text{mod}\ L) \\ \Leftrightarrow(m-n)\cdot t+L\cdot k=y-x(t,k为变量) \]

的整数解。求出最小的非负整数 \(t\) 即可。

代码写得有点乱。

/**
 * poj1061 青蛙的约会
 *
 */

#include <iostream>
#include <climits>
#include <cmath>
#include <iomanip>
#include <vector>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;

typedef long long LL;

void exgcd(LL a, LL b, LL &x, LL &y)
{
    if (b == 0) {
        x = 1, y = 0;
        return;
    }
    exgcd(b, a%b, y, x);
    y -= a/b*x;
    //cout << a << '#' << b << '#' << x << '#' << y << endl;
}

int main()
{
    int x,y,m,n,L;
    scanf("%d%d%d%d%d", &x, &y, &m, &n, &L);
    LL a=m-n, b=L, c=y-x, d=__gcd(a,b), x0, y0;
    if (c%d) {
        puts("Impossible");
        return 0;
    }
    if (a<0) a=-a, c=-c;
    exgcd(a,b,x0,y0);
    //cout << a << '#' << b << '#' << x << '#' << y << endl;
    if (d < 0) d = -d;
    x0 *= c/d;
    b /= d;
    printf("%lld\n", (x0%b+b)%b);
    return 0;
}

posted @ 2021-02-16 20:33  Zewbie  阅读(39)  评论(0编辑  收藏  举报