扩展欧几里得
两个青蛙跑步,跑的快的,追上跑得慢的。 并且多跑的路程有 L 的整数倍。
本题要点:
1、假设 A 青蛙 起点 m, 速度为 a, B 青蛙 起点 n, 速度为 b; 如果 a > b, 跑了 x 步,
ax + m - (bx + n) = L * y, 化简为:
(a - b) * x + L * (-y) = n - m;
这里的 n - m 可能是负数,通过模 L , 使得 方程 右边是正整数。从而得到方程: ax + by = c,
(a, b, c 都是正整数)
2、 如果 a < b, 同样的处理方法
3、 利用 扩展欧几里得exgcd, 可以求出 方程 (a - b) * x + L * (-y) = n - m;
x取最小正整数的解了。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
using namespace std;
typedef long long ll;
ll a, b, m, n, L;
ll exgcd(ll a, ll b, ll& x, ll& y)
{
if(0 == b)
{
x = 1, y = 0;
return a;
}
ll d = exgcd(b, a % b, x, y);
ll z = x; x = y; y = z - y * (a / b);
return d;
}
void solve()
{
ll c, d, e;
if(a < b)
{
c = b - a, e = (m - n + L) % L;
}else{
c = a - b, e = (n - m + L) % L;
}
d = L;
// c * x + d * y = e 解方程
ll x0, y0;
ll g = exgcd(c, d, x0, y0);
// printf("c = %lld, d = %lld, e = %lld, g = %lld\n", c, d, e, g);
if(e % g)
{
printf("Impossible\n");
return;
}
ll m1 = d / g, x = e / g * x0;
ll min_x = (x % m1 + m1) % m1;
printf("%lld\n", min_x);
}
int main()
{
scanf("%lld%lld%lld%lld%lld", &m, &n, &a, &b, &L);
solve();
return 0;
}
/*
1 2 3 4 5
*/
/*
4
*/