题目:青蛙的约会
题目链接:https://vjudge.net/contest/351853#problem/F
题目描述:
一个L长的环上有两个点(x,y),它们每次往一个方向移动m,n
问是否可以相遇,如果可以,那么是第几次移动。
题目分析:
由关系可以列等式:(x+km)%L=(y+kn)%L,
移项得x-y=k(n-m)+pL
也就是求ax+by=c对于x的最小正数解。
步骤1:先求ax+by=gcd(a,b)的一个特解(x0,y0)
步骤2:判断c是否是gcd(a,b)的倍数,而知有无解。
步骤3:如果有解,把x0与y0乘上c/gcd(a,b),得到ax+by=c的一个特解。
步骤4:x0对b/gcd(a,b)取模(小心x0为负数)可得x0的最小正数解(暂时不讨论原因)。
代码:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
long long exgcd(long long a,long long b,long long &c,long long &d)
//先求个ax+by=gcd(a,b)的特解
{
long long k=a;
if(b)
{
k=exgcd(b,a%b,d,c);
d-=(a/b)*c;
}
else
{
c=1;
d=0;
}
return k;
}
int main()
{
long long x,y,m,n,L,e,f,g,h,x0,y0;
scanf("%lld%lld%lld%lld%lld",&x,&y,&m,&n,&L);
f=x-y;
g=n-m;
if(g<0) {f=-f;g=-g;} //使a保持为正
e=exgcd(g,L,x0,y0); //求ax+by=gcd(a,b)一个特解
if(f%e)
{
printf("Impossible\n");
}
else
{
h=L/e;
x0*=f/e; //转换为ax+by=c的特解
x0=(x0%h+h)%h;//找最小正数解
printf("%lld\n",x0);
}
return 0;
}
在这里插入代码片