Codeforces140CNew Year Snowmen

一道优先队列好题

不难发现,每次取最多的几个雪球能保证凑出来的雪人最多,然后我们就先离散化一下,然后封装丢到优先队列里,每次取出队首的三个,将数量各自减一 ,表示凑了一个雪人,然后将数量大于一的再丢回去,直到剩余种数小于3为止

代码

//By AcerMo
#include
#include
#include
#include
#include
#include
using namespace std;
const int M=100500;
int n,a[M],b[M],c[M];
struct emm
{
	int v,id;
	bool friend operator < (emm a,emm b)
	{
		return a.v<b.v;
	} 
}ad;
struct an{int a,b,c;}e[M];
priority_queue<emm>q;
inline int read()
{
	int x=0;char ch=getchar();
	while (ch>'9'||ch<'0') ch=getchar();
	while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
	return x;	
}
signed main()
{
	n=read();int cnt=0,s=0,tot=0;
	for (int i=1;i<=n;i++) a[i]=read();
	sort(a+1,a+n+1);
	for (int i=1;i<=n;i++)
	if (a[i]==a[i-1]) b[cnt]++;
	else b[++cnt]++,c[cnt]=a[i];
	for (int i=1;i<=cnt;i++)
		ad.id=c[i],ad.v=b[i],q.push(ad);
	if (q.size()<3) return puts("0"),0;
	while (q.size()>=3)
	{
		emm x=q.top();q.pop();
		emm y=q.top();q.pop();
		emm z=q.top();q.pop();
		s++;x.v--;y.v--;z.v--;
		e[++tot].a=x.id;e[tot].b=y.id;e[tot].c=z.id;
		if (e[tot].a<e[tot].b) swap(e[tot].a,e[tot].b);
		if (e[tot].a<e[tot].c) swap(e[tot].a,e[tot].c);
		if (e[tot].b<e[tot].c) swap(e[tot].b,e[tot].c);
		if (x.v>0) q.push(x);
		if (y.v>0) q.push(y);
		if (z.v>0) q.push(z);
	}
	printf("%d\n",s);
	for (int i=1;i<=tot;i++)
	printf("%d %d %d\n",e[i].a,e[i].b,e[i].c);
	return 0;
}

你可能感兴趣的:(数据结构-堆)