【BZOJ2529】[Poi2011]Sticks 贪心

【BZOJ2529】[Poi2011]Sticks

Description

给出若干木棍,每根木棍有特定的颜色和长度。问能否找到三条颜色不同的木棍构成一个三角形。
(注意这里所说的三角形面积要严格大于0)

第一行给出一个整数k(3<=k<=50),表示颜色的种数。这k种颜色被标号为1至k。
接下来k行,第i+1描述颜色为i的木棍的信息。
首先一个整数Ni(1<=Ni<=10^6)表示颜色为i的木棍的数量。
接下来Ni个整数,表示这Ni根木棍各自的长度。
所有木棍的长度<=10^9。总木棍数量<=10^6。

你的程序应该仅输出一行
如果有解,输出6个整数,分别表示第一条边的颜色,第一条边的长度,第二条边的颜色,第二条边的长度,第三条边的颜色,第三条边的长度,这六个整数以空格分割。
如果有多组解,随便输出一组即可。
如果无解,输出 NIE

 

Sample Input

4
1 42
2 6 9
3 8 4 8
1 12

Sample Output

3 8 4 12 2 9

题解:先将所有木棍排序,然后枚举最长的木棍,我们需要在所有比它小的木棍中找到最大的且颜色不同的两根与它比较。一开始以为用堆,但其实只需要维护最长的3根不同颜色的就行了。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=1000010;
int m,n;
struct stick
{
	int col,len;
}p[maxn],s[5];
bool cmp(stick a,stick b)
{
	return a.len<b.len;
}
inline int rd()
{
	int ret=0,f=1;	char gc=getchar();
	while(gc<'0'||gc>'9')	{if(gc=='-')f=-f;	gc=getchar();}
	while(gc>='0'&&gc<='9')	ret=ret*10+gc-'0',gc=getchar();
	return ret*f;
}
int main()
{
	m=rd();
	int i,j,a;
	for(i=1;i<=m;i++)
	{
		a=rd();
		for(j=1;j<=a;j++)	p[++n].col=i,p[n].len=rd();
	}
	sort(p+1,p+n+1,cmp);
	for(i=1;i<=n;i++)
	{
		for(j=0;j<3;j++)	if(p[i].col==s[j].col)
		{
			s[j]=p[i],sort(s,s+3,cmp);
			break;
		}
		if(j==3)	s[0]=p[i],sort(s,s+3,cmp);
		if(s[0].len+s[1].len>s[2].len)
		{
			printf("%d %d %d %d %d %d",s[0].col,s[0].len,s[1].col,s[1].len,s[2].col,s[2].len);
			return 0;
		}
	}
	printf("NIE");
	return 0;
}
posted @ 2017-08-24 08:16  CQzhangyu  阅读(301)  评论(0编辑  收藏  举报