【复赛模拟试题】圆周上的追击(数论-扩展欧几里得算法)

Description
  在一个周长为 n+1 公里的圆周上每隔 1 公里有个驿站,顺时针方向编号依次为0,1,2,…,n。现在甲乙两人分别从圆周上某驿站出发,按顺时针方向前进。甲从编号为 i 的驿站出发,每天走 a 公里,然后休息;乙从编号为 j 的驿站出发,每天行走 b 公里,然后休息。问最少多少天,他们才能休息在同一个驿?

Input
  一行四个整数输入:n,i,j,a,b

Output

  一个整数,表示最少多少天他们能在同一驿站休息,如果永远也不会有这种情况发生,输出-1。


分析:

这个题跟青蛙约会是一样的,就是扩展欧几里得。不过个人为了方便理解,还是避免了0,对应n,i,j都要加一。

#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
LL exgcd(LL a,LL b,LL &x,LL &y)
{
	if(b==0){x=1; y=0; return a;}
	LL xx,yy;
	LL g=exgcd(b,a%b,xx,yy);
	x=yy; y=xx-(a/b)*yy;
	return g;
}
int main()
{
//	freopen("in.txt","r",stdin);
	LL n,a,b,c,i,j;
	scanf("%lld%lld%lld%lld%lld",&n,&i,&j,&a,&b);
	n++; a=(a+1)%n; b=(b+1)%n;
	a=a-b; b=-n; c=j-i;
	LL x0,y0;
	LL g=exgcd(a,b,x0,y0);
	if(c%g!=0){printf("-1");return 0;}
	x0*=c/g; b=abs(b/g);
	LL ans=(x0%b+b)%b;
	printf("%lld",ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/wwwengine/article/details/81008986