http://poj.org/problem?id=1061 (题目链接)
题意
两只青蛙在周长为L的球上沿一条直线向一个方向跳,每只每次分别跳m,n米,它们一开始分别在X,Y处,问跳几次两青蛙可以在同一点上。
Solution
设需要跳t次,我们可以列出方程:${m*t+X=n*t+Y(mod~L)}$,化简为:${(m-n)*t=Y-X(mod~L)}$,${(m-n)*t+L*s=Y-X}$。是不是很眼熟,没错就是扩展欧几里得算法。
代码
// uoj147 #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> #include<queue> #define MOD 1000000007 #define inf 2147483640 #define LL long long #define free(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout); using namespace std; void exgcd(LL a,LL b,LL &d,LL &x,LL &y) { if (!b) {d=a;x=1,y=0;return;} exgcd(b,a%b,d,y,x); y-=a/b*x; } int main() { LL x,y,d,X,Y,n,m,L; scanf("%lld%lld%lld%lld%lld",&X,&Y,&m,&n,&L); X--,Y--; if (X==Y) {printf("0");return 0;} LL a=((m-n)%L+L)%L,c=((Y-X)%L+L)%L; exgcd(a,L,d,x,y); if (c%d!=0) {printf("Impossible");return 0;} x=(x*(c/d)%(L/d)+L/d)%(L/d); printf("%lld",x); return 0; }