BZOJ1407[Noi2002]Savage

emm,扩欧的裸题,我们不难发现,如果两个野人不相遇,当且仅当他们能走到一个洞穴时,双方都死了或者根本走不到一起

所以我们可以列出

> now[i]+pass[i]*k ≡ now[j]+pass[j]*k (mod m)

> now[i]-now[j] ≡ (pass[j]-pass[i])*k (mod m)

这时我们发现这时一个同余式,可以用ecgcd求解k的值,来判断他们是否能在寿命内相遇

代码

//By AcerMo
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int M=50;
int n;
int now[M],life[M],pass[M];
int exgcd(int a,int b,int &x,int &y)
{
	if (!b)
	{
		x=1;y=0;return a;
	}
	int d=exgcd(b,a%b,x,y);
	int z=x;x=y;y=z-(a/b)*y;
	return d;
}
bool check(int m)
{
	for (int i=1;i<n;i++)
		for (int k=i+1;k<=n;k++)
		{
			int a=((now[k]-now[i])%m+m)%m;
			int b=((pass[i]-pass[k])%m+m)%m;
			int x,y,d;
			d=exgcd(b,m,x,y);
			if (a%d!=0) continue;
			a/=d;int mini=m/d;
			int e=(a*x%mini+mini)%mini;
			if (e<=life[i]&&e<=life[k]) return 0;
		}
	return 1;		
}
int main()
{
	scanf("%d",&n);int m=0;
	for (int i=1;i<=n;i++)
		scanf("%d%d%d",&now[i],&pass[i],&life[i]),m=max(m,now[i]);
	for (int i=m;;i++)
		if (check(i)) 
			return cout<<i,0;//压行新姿势
	return 0; 
}

猜你喜欢

转载自blog.csdn.net/acerandaker/article/details/80879645