题意
青蛙A每天走
m
m
m,青蛙B每天走
n
n
n,它们在一个环形的轨道上,轨道长度为
l
l
l,青蛙A的初始位置为
a
a
a,青蛙B的初始位置为
b
b
b.
求:青蛙走多少天才可以相遇?
题解
设青蛙走
x
x
x天可以相遇,则可以列出方程
m
x
+
a
−
(
n
x
+
b
)
=
k
l
mx+a-(nx+b)=kl
mx+a−(nx+b)=kl
整理可得:
(
n
−
m
)
x
+
k
l
=
a
−
b
(n-m)x+kl=a-b
(n−m)x+kl=a−b可以看出这是一个
a
x
+
b
y
=
c
ax+by=c
ax+by=c的式子,可以用拓展欧几里得,求出一个
(
n
−
m
)
x
+
k
l
=
g
c
d
(
n
−
m
,
l
)
(n-m)x+kl=gcd(n-m,l)
(n−m)x+kl=gcd(n−m,l)的解
x
,
y
x,y
x,y
由于不确定
n
,
m
n,m
n,m的大小,需要分类讨论一下
(
n
−
m
)
x
+
k
l
=
a
−
b
(
n
>
m
)
(n-m)x+kl=a-b (n>m)
(n−m)x+kl=a−b(n>m)
(
m
−
n
)
x
+
(
−
k
)
l
=
b
−
a
(
n
<
m
)
(m-n)x+(-k)l=b-a (n<m)
(m−n)x+(−k)l=b−a(n<m)
因为我们不需要求
k
k
k的大小,只需要求 x,所以我们只处理系数变换。
最后我们需要求出来的应该是一个最小正整数 x m i n x_{min} xmin
经过拓展欧几里得,我们可以求出:
(
n
−
m
)
x
+
k
l
=
g
c
d
(
n
−
m
,
l
)
(n-m)x+kl=gcd(n-m,l)
(n−m)x+kl=gcd(n−m,l)的一个特解
(
x
,
y
)
(x,y)
(x,y)
x
=
x
a
−
b
g
c
d
(
n
−
m
,
l
)
x=x\frac{a-b}{gcd(n-m,l)}
x=xgcd(n−m,l)a−b
得到
(
n
−
m
)
x
+
k
l
=
a
−
b
(n-m)x+kl=a-b
(n−m)x+kl=a−b的一个特解
这个方程式的通解为
X
=
x
m
i
n
+
k
b
g
c
d
(
n
−
m
,
l
)
(
k
∈
Z
)
X=x_{min}+k\frac{b}{gcd(n-m,l)}(k\in Z)
X=xmin+kgcd(n−m,l)b(k∈Z)
那么
x
m
i
n
=
X
%
(
b
g
c
d
(
n
−
m
,
l
)
)
x_{min}=X\%(\frac{b}{gcd(n-m,l)})
xmin=X%(gcd(n−m,l)b);
因为有求出来
x
<
0
x<0
x<0的情况
x
m
i
n
=
[
x
%
(
b
g
c
d
(
n
−
m
,
l
)
)
+
b
g
c
d
(
n
−
m
,
l
)
]
%
(
b
g
c
d
(
n
−
m
,
l
)
)
x_{min}=[x\%(\frac{b}{gcd(n-m,l)})+\frac{b}{gcd(n-m,l)}]\%(\frac{b}{gcd(n-m,l)})
xmin=[x%(gcd(n−m,l)b)+gcd(n−m,l)b]%(gcd(n−m,l)b)
代码
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
ll m,n,a,b,l;
ll gcd;
void ex_gcd(ll a,ll b,ll &x,ll &y){
if(b){
ex_gcd(b,a%b,x,y);
ll t=x;
x=y;
y=t-(a/b)*y;
}
else{
x=1,y=0;
gcd=a;
}
return;
}
int main()
{
cin>>a>>b>>m>>n>>l;
ll x=0,y=0;
ll c=a-b;
if(n-m>0)
ex_gcd(n-m,l,x,y);
else{
c=-c;
ex_gcd(m-n,l,x,y);
}
if(c%gcd!=0){
cout<<"Impossible"<<endl;
return 0;
}
ll t=l/gcd;
x*=(c/gcd);
x=(x%t+t)%t;
cout<<x<<endl;
}