题解 P1516 【青蛙的约会】


P1516 青蛙的约会

题目大意:

有一个长度为 \(l\) 的圆环,圆环上有两个点 \(A,B\) ,分别位于 \(x,y\) ,每次分别可跳 \(m,n\) 个单位,问跳多少次相遇。无解输出 Impossible

solution:

对此可列出同余方程:

\[(x+am)\equiv (y+an)(\bmod l) \]

展开:

\[(x+am)-(y+an)=bl \]

\[x-y+a(m-n)=bl \]

\[a(m-n)-bl=y-x \]

这里 \(a,b\) 即为我们所求。扩欧后推广解就行了。但由于 \(x=x_0+ k\frac{b}{\gcd(a,b)}\) ,所以求最小正整数要对 \(\frac{b}{\gcd(a,b)}\) 取模。

细节处理:

  • 开LL。
  • 注意无解情况。
代码
#include
using namespace std;
typedef long long LL;
LL xx,yy;
inline int exgcd(int a,int b){
    if(!b){
        xx=1,yy=0;
        return a;
    }
    int d=exgcd(b,a%b);
    LL tx=xx;
    xx=yy,yy=tx-a/b*yy;
    return d;
}
int main(){
    int x,y,m,n,l; 
    scanf("%d%d%d%d%d",&x,&y,&m,&n,&l);
    int n_m=(n%l-m%l+(LL)l)%l,x_y=(x%l-y%l+(LL)l)%l;//处理下负数
    int d=exgcd(n_m,l);
    if(x_y%d!=0) return puts("Impossible"),0;//特判无解
    xx=(x_y/d*xx%(l/d)+(l/d))%(l/d);//推广
    printf("%lld",xx);
    return 0;
}

End