青蛙的约会(扩欧模板)

洛咕

poj

题意:在长度为L米的环形操场上,青蛙A从x点出发,每一步跳m米,青蛙B从y点出发,每一步跳n米.两只青蛙运动的方向相同,求跳多少步能够相遇(相遇:当且仅当两只青蛙同一时刻在同一个坐标点上)

分析:设两只青蛙跳了t步,则A的坐标为\(x+m*t\),B点的坐标为\(y+n*t\),他们相遇的充要条件是\(x+m*t-(y+n*t)=k*L\),其中k是整数.

整理一下上式得,\(t*(n-m)+k*L=x-y\)

恩,用扩展欧几里得求解方程,即\(exgcd(n-m,L,x_0,y)\),则\(x_0\)是方程的一个解

根据定理:对于方程ax+by=c,它有解当且仅当gcd(a,b)|c.则若\((x-y) \mod gcd(n-m,L)\)不等于0,则方程无解,青蛙不能相遇,根据实际情况,若m等于n,则青蛙也不能相遇.

\(d=gcd(n-m,L)\),方程的特解为\(x=x_0*(x-y)/d\)

则最小正整数解为\((x\mod(L/d)+(L/d))\mod(L/d)\)

#include<iostream>
#include<cstdio>
#define LL long long
using namespace std;
LL x,y,m,n,L;
LL exgcd(LL a,LL b,LL &x,LL &y){
    if(b==0){x=1;y=0;return a;}
    LL d=exgcd(b,a%b,y,x);
    y-=(a/b)*x;
    return d;
}
int main(){
    scanf("%lld%lld%lld%lld%lld",&x,&y,&m,&n,&L);
    if(n<m){swap(m,n);swap(x,y);}
    LL a,b,d=exgcd(n-m,L,a,b);
    if((x-y)%d!=0||m==n)printf("Impossible\n");
    else printf("%lld",(a*(x-y)/d%(L/d)+(L/d))%(L/d));
    return 0;
}

posted on 2019-03-09 15:12  PPXppx  阅读(137)  评论(0编辑  收藏  举报