列表

详情


NC50574. 荒岛野人

描述

克里特岛以野人群居而著称。岛上有排列成环行的M个山洞。这些山洞顺时针编号为
岛上住着N个野人,一开始依次住在山洞中,以后每年,第i个野人会沿顺时针向前走P_i个洞住下来。每个野人i有一个寿命值L_i,即生存的年数。下面四幅图描述了一个有6个山洞,住有三个野人的岛上前四年的情况。三个野人初始的洞穴编号依次为1,2,3;每年要走过的洞穴数依次为3,7,2;寿命值依次为4,3,1。
奇怪的是,虽然野人有很多,但没有任何两个野人在有生之年处在同一个山洞中,使得小岛一直保持和平与宁静,这让科学家们很是惊奇。他们想知道,至少有多少个山洞,才能维持岛上的和平呢?

输入描述

第一行为一个整数N,即野人的数目;
第二行到第N+1每行为三个整数C_i,P_i,L_i,表示每个野人所住的初始洞穴编号,每年走过的洞穴数及寿命值。

输出描述

仅包含一个数M,即最少可能的山洞数。输入数据保证有解,且M不大于

示例1

输入:

3
1 3 4
2 7 3
3 2 1

输出:

6

说明:

该样例对应于题目描述中的例子。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 435ms, 内存消耗: 480K, 提交时间: 2019-08-26 15:53:53

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int c[20],p[20],l[20];
int n;
ll exgcd(ll a,ll b,ll &x,ll &y){
	if(!b){
		x=1;
		y=0;
		return a;
	}
	ll d=exgcd(b,a%b,x,y);
	ll t=x;
	x=y;
	y=t-y*(a/b);
	return d;
}
int check(int m){
	for(int i=1;i<n;i++){
		for(int j=i+1;j<=n;j++){
			ll a=p[i]-p[j],x=0,b=m,y=0,c1=c[j]-c[i];
			ll d=exgcd(a,b,x,y);
			if(c1%d)
				continue;
			x=x*c1/d;
			ll p1=b/d;
			x%=p1;
			if(x<0)
				x+=abs(p1);
			if(x<=min(l[i],l[j]))
				return 0;
		}
	}
	return 1;
}
int main(){
	scanf("%d",&n);
	int mx=-1;
	for(int i=1;i<=n;i++)
		scanf("%d%d%d",&c[i],&p[i],&l[i]),mx=max(mx,c[i]);
	for(int i=mx;i<=1e6+5;i++){
		if(check(i)){
			printf("%d\n",i);
			break;
		}
	}
	return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 311ms, 内存消耗: 380K, 提交时间: 2020-10-11 21:31:34

#include<bits/stdc++.h>
using namespace std;
const int nm=1000000;
int n,m,x,y,c,d,lb;
void euc(int a,int b,int&x,int&y){
	if(!b)x=1,y=0,d=a;
	else euc(b,a%b,y,x),y-=a/b*x;
}struct savage{int c,p,l;}s[nm];
bool cmp(savage a,savage b){return a.p>b.p;}
bool check(int m){
	for(int i=0;i<n;i++)
		for(int j=i+1;j<n;j++){
			euc(s[i].p-s[j].p,m,x,y);
			if((c=s[j].c-s[i].c)%d)continue;
			x*=(c/d),d=m/d,x=(x%d+d)%d;
			if(x<=s[i].l&&x<=s[j].l)return false;
		}return true;
}int main(){
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%d%d%d",
		&s[i].c,&s[i].p,&s[i].l);
		lb=max(lb,s[i].c);
	}sort(s,s+n,cmp);
	for(int i=lb;i<=nm;i++)
	if(check(i))return printf("%d\n",i),0;
}

上一题