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;
}