1. 程式人生 > >【BZOJ2529】[Poi2011]Sticks 貪心

【BZOJ2529】[Poi2011]Sticks 貪心

cpp inline 排序 line 三角形 pre out truct using

【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;
}

【BZOJ2529】[Poi2011]Sticks 貪心