不妨设青蛙A的出发点坐标是 m 1 m1 m1,青蛙B的出发点坐标是 n 1 n1 n1。青蛙A一次能跳 m m m米,青蛙B一次能跳 n n n米,跳一圈长 l l l米,设青蛙A、B跳了 x x x次。
那么题目要求的是满足下面这个柿子最小 x x x正整数解:
( m − n ) × x ≡ m 1 − n 1 ( m o d l ) (m-n)\times x\equiv m1-n1\pmod{l} (m−n)×x≡m1−n1(modl)
不妨把这个不定方程变形一下:
( m − n ) × x + l × y = m 1 − n 1 (m-n)\times x+l\times y=m1-n1 (m−n)×x+l×y=m1−n1
看到这个形式,就想到用扩展欧几里得来求解。
不妨设 a = m − n , b = l , c = m 1 − n 1 a=m-n,b=l,c=m1-n1 a=m−n,b=l,c=m1−n1。
那么原方程就是:
a × x + b × y = c a\times x+b\times y=c a×x+b×y=c
然后我们知道一个性质:
若 a × x + b × y = c a\times x+b\times y=c a×x+b×y=c有解,则满足 g c d ( a , b ) ∣ c gcd(a,b)|c gcd(a,b)∣c。
所以说我们先判断方程是否有解,若无解就输出 I m p o s s i b l e \mathbf{Impossible} Impossible。
然后如果有解,我们就先用扩展欧几里得求出 a × x + b × y = g c d ( a , b ) a\times x+b\times y=gcd(a,b) a×x+b×y=gcd(a,b)的一组解。
然后我们对这个方程左右两边同时乘上 c ÷ g c d ( a , b ) c\div gcd(a,b) c÷gcd(a,b)。
那么有:
a × ( c ÷ g c d ( a , b ) ) × x + b × ( c ÷ g c d ( a , b ) ) × y = c a\times(c\div gcd(a,b))\times x+b\times(c\div gcd(a,b))\times y=c a×(c÷gcd(a,b))×x+b×(c÷gcd(a,b))×y=c
为了方便起见,我们这里令 p = a × ( c ÷ g c d ( a , b ) ) p=a\times(c\div gcd(a,b)) p=a×(c÷gcd(a,b)), q = b × ( c ÷ g c d ( a , b ) ) q=b\times(c\div gcd(a,b)) q=b×(c÷gcd(a,b))。
这时,我们就可以求出满足下列方程的一组特解:
p × x + q × y = c p\times x+q\times y=c p×x+q×y=c
此时,我们发现 x x x可以任意变为 ( x + k × q g c d ( p , q ) ) (x+k\times \frac{q}{gcd(p,q)}) (x+k×gcd(p,q)q),且总有对应的一个整数解 y y y使得原方程依旧成立,因为:
若 p × x + q × y = c p\times x+q\times y=c p×x+q×y=c成立,则必有 p × ( x + q g c d ( p , q ) ) + q × ( y − p g c d ( p , q ) ) = c p\times (x+\frac{q}{gcd(p,q)})+q\times (y-\frac{p}{gcd(p,q)})=c p×(x+gcd(p,q)q)+q×(y−gcd(p,q)p)=c 成立。
(为什么一定要除 g c d ( p , q ) gcd(p,q) gcd(p,q)?因为在电脑中会向下取整,而且我们要使得 q g c d ( p , q ) \frac{q}{gcd(p,q)} gcd(p,q)q尽量小,这样才能找到更多的 x x x解)。
所以令 g = q g c d ( p , q ) g=\frac{q}{gcd(p,q)} g=gcd(p,q)q,即:
g = q g c d ( p , q ) = b × ( c ÷ g c d ( a , b ) ) g c d ( a × ( c ÷ g c d ( a , b ) ) , b × ( c ÷ g c d ( a , b ) ) ) = q g c d ( a , b ) g=\frac{q}{gcd(p,q)}=\frac{b\times(c\div gcd(a,b))}{gcd(a\times(c\div gcd(a,b)),b\times(c\div gcd(a,b)))}=\frac{q}{gcd(a,b)} g=gcd(p,q)q=gcd(a×(c÷gcd(a,b)),b×(c÷gcd(a,b)))b×(c÷gcd(a,b))=gcd(a,b)q
那么 x x x的最小正整数解为:
( ( x m o d g ) + g ) m o d g ((x \bmod g)+g)\bmod g ((xmodg)+g)modg
那么我们就可以输出答案了。
代码流程梳理一下:
最后代码如下:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll m1,n1,m,n,l;
ll exgcd(ll a,ll b,ll &x,ll &y)
{
if(!b)
{
x=1ll,y=0ll;
return a;
}
ll ans=exgcd(b,a%b,x,y);
ll xx=x;
x=y;
y=xx-(a/b)*y;
return ans;
}
int main()
{
while(~scanf("%lld%lld%lld%lld%lld",&m1,&n1,&m,&n,&l))
{
if(n<m)
{
swap(n,m);
swap(n1,m1);
}
ll a=n-m,b=l,c=m1-n1,x,y;
ll t=exgcd(a,b,x,y);
if(c%t)
{
puts("Impossible");
continue;
}
c/=t;
x*=c;
ll mod=b/t;
x=(x%mod+mod)%mod;
printf("%lld\n",x);
}
return 0;
}