B
题意:
有两只青蛙,青蛙
A
A
A和青蛙
B
B
B。他们在一个长度为
L
L
L米的圆形操场上,青蛙
A
A
A初始在坐标
a
a
a上,每次跳跃可以跳
m
m
m米,青蛙
B
B
B初始在坐标
b
b
b上,每次跳跃可以跳
n
n
n米。
两只青蛙在任意时刻的跳跃次数都是相同的,问至少跳多少次两者会相遇。
数据范围:
a
≠
b
,
0
≤
a
,
b
<
2
×
1
0
9
,
0
<
m
,
n
<
2
×
1
0
9
,
0
<
L
<
2.1
×
1
0
9
a\neq b,0\leq a, b<2\times 10^9,0<m,n<2\times 10^9,0<L<2.1\times 10^9
a=b,0≤a,b<2×109,0<m,n<2×109,0<L<2.1×109
题解:
考虑两只青蛙距离差为:
b
−
a
b-a
b−a,设青蛙
A
,
B
A,B
A,B需要跳跃
x
x
x次才能相遇,
则有等式:
(
n
−
m
)
x
≡
(
b
−
a
)
(
m
o
d
L
)
(n-m)x\equiv (b-a)(\mod L)
(n−m)x≡(b−a)(modL)
转换一下:
(
n
−
m
)
x
+
L
y
=
(
b
−
a
)
(n-m)x+Ly=(b-a)
(n−m)x+Ly=(b−a)
(这里要注意 ( n − m ) (n-m) (n−m)和 L L L都要为正数,所以当 ( n − m ) < 0 (n-m)<0 (n−m)<0,可以乘上一个 − 1 -1 −1使得等式转换为: ( m − n ) x + L × ( − y ) = a − b (m-n)x+L\times(-y)=a-b (m−n)x+L×(−y)=a−b)
通过
e
x
g
c
d
exgcd
exgcd可以求出一个
x
0
x_0
x0,然后扩大
b
−
a
g
c
d
(
n
−
m
,
L
)
\frac{b-a}{gcd(n-m,L)}
gcd(n−m,L)b−a倍。
由于
x
1
=
x
0
+
k
L
g
c
d
(
n
−
m
,
L
)
x_1=x_0+k\frac{L}{gcd(n-m,L)}
x1=x0+kgcd(n−m,L)L,所以对整体取模即可,注意负数问题皆可抛给
k
k
k,因此实际用的是
a
b
s
(
L
g
c
d
(
n
−
m
,
L
)
)
abs(\frac{L}{gcd(n-m,L)})
abs(gcd(n−m,L)L)这个值。
代码:
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
ll exgcd(ll a, ll b, ll &x, ll &y) {
if(!b) {
x = 1;
y = 0;
return a;
}
ll d = exgcd(b, a % b, y, x);
y -= a / b * x;
return d;
}
int main()
{
ll sta, stb, m, n, L;
scanf("%lld%lld%lld%lld%lld", &sta, &stb, &m, &n, &L);
ll a = m - n, b = L;
ll x, y;
ll g = exgcd(a, b, x, y);
if((stb - sta) % g) puts("Impossible");
else {
x *= (stb - sta) / g;
ll mod = b / g;
if(mod < 0) mod = -mod;
printf("%lld\n", (x % mod + mod) % mod);
}
return 0;
}