版权声明:我这么弱的蒟蒻,虽然博文不是很好,但也请标明转发地址喵! https://blog.csdn.net/ACerAndAKer/article/details/82845187
一道优先队列好题
不难发现,每次取最多的几个雪球能保证凑出来的雪人最多,然后我们就先离散化一下,然后封装丢到优先队列里,每次取出队首的三个,将数量各自减一 ,表示凑了一个雪人,然后将数量大于一的再丢回去,直到剩余种数小于3为止
代码
//By AcerMo
#include<queue>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
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;
}