P1516 青蛙的约会
根据题意可以列出方程:
设走了X步,已经绕了维度线Y圈
那么 nX-mX=LY+(x-y)
稍微转换一下: (n-m)X - LY = x-y
如果设 A=n-m,B=-L,C=x-y
那就变成了AX+BY=C的形式
直接套exgcd就可以得到一组AX+BY=gcd(A,B)的解
根据基本的数学知识,原方程有解当且仅当 gcd(A,B) | C 时
然后把X和Y乘一个C/gcd(A,B)就是原方程的一组解(X,Y)了
然后要注意n-m为负的情况,要把方程两边同时乘-1(A=-A,C=-C)
Y的符号不重要,所以B乘不乘-1都没关系
然后考虑得到一组解后如何求出最小解
可以发现两只青蛙每走L/gcd(L,A)步后就都会回到出发点
所以只要把答案对L/gcd(L,A)取模就是最小解了
还要注意答案是负数的情况,这时答案为 (X%mo+mo)%mo
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> 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 g=exgcd(b,a%b,x,y); ll t=x; x=y; y=t-a/b*y; return g; } ll n,m,x,y,L; ll d,X,Y; int main() { cin>>x>>y>>m>>n>>L; ll A=n-m,B=x-y;//这里的B就是上面说的C if(A<0) A=-A,B=-B; d=exgcd(A,L,X,Y); if(B%d) { printf("Impossible"); return 0; } ll ans=X*B/d,mo=L/d; printf("%lld",(ans%mo+mo)%mo); return 0; }