Description
现在来做雪人,每个雪人由三个不同大小的雪球构成:一个大的,一个中等的,一个小的。现在有 n 个雪球半径分别为 r1, r2, ..., rn. 为了做雪人,三个雪球的大小必须两两不同。例如,半径分别为 1,2,3 的雪球可以做成雪人,但 2, 2, 3 或 2, 2, 2 不行。现在需要尽可能做更多雪人。
Input
第一行是一个整数 n (1 ≤ n ≤ 105) — 雪球的数量. 接下来有n行整数 — 雪球的半径 r1, r2, ..., rn (1 ≤ ri ≤ 109).
Output
第一行是一个数 k — 最大的雪人数. 接下来k行是每个雪人的描述 — 大雪球的半径,中等雪球的半径,小雪球的半径. 允许按任意顺序输出雪人描述. 如果有多种方案,输出任意一个
Sample Input
Input
7
1 2 3 4 5 6 7
Output
2
3 2 1
6 5 4
Input
3
2 2 3
Output
0
思路:我们要堆更多的雪人而且三种雪球的大小不能相等,基于贪心的思想,我们要优先用完雪球数量多的雪球,
举个例子: 2 2 2 3 3 如果先使用数量小的,那么一会就没了 只能做两个,如果使用数量多的,那么堆得要比两个多;
这里我们根据每种雪球的数量进行从大到小的优先队列,然后用map存储的对应每个大小雪球的数量,每次优先去三个数量最多且大小不同的雪球,并对他们按照从大到小排序存入ans数组最后输出结果,如果取出对应半径的雪球后数量还不为0,那么继续入队;知道队列为空 或者不够三个了;
传送门:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<map>
#include<queue>
#include<algorithm>
#define N 100010
using namespace std;
int n;
int r[N];
int sum[N][4];
struct node
{
friend bool operator <(node x,node y)
{ return x.num<y.num;
}
int num;
int d;
}p[N];
int main()
{
int i,j;
scanf("%d",&n);
priority_queue<node>Q;
map <int,int> q;
for(i=1;i<=n;i++)
{ scanf("%d",&r[i]);
q[r[i]]++;
//printf("%d\n",q[r[i]]);
}
int k=0;
for(i=1;i<=n;i++)
{ if(q[r[i]]!=0)
{ p[k].d=r[i];
//printf("%d\n",p[k].d);
p[k].num=q[r[i]];
Q.push(p[k]);
k++;
q[r[i]]=0;
}
}
k=0;
node a,b,c;
int f[3];
while(!Q.empty())
{ a=Q.top();
//printf("%d\n",a.d);
f[0]=a.d;
Q.pop();
a.num--;
if(Q.empty())//前两次没取出top就要判断是否为空,(每个雪球大小不等),若为空则不能堆出雪人;
break;
b=Q.top();
f[1]=b.d;
Q.pop();
b.num--;
if(Q.empty())
break;
c=Q.top();
f[2]=c.d;
Q.pop();
c.num--;
sort(f,f+3);
//printf("%d %d %d",f[2],f[1],f[0]);
sum[k][0]=f[2];
sum[k][1]=f[1];
sum[k][2]=f[0];
k++;
if(a.num>0)
Q.push(a);
if(b.num>0)
Q.push(b);
if(c.num>0)
Q.push(c);
}
printf("%d\n",k);
for(i=0;i<k;i++)
printf("%d %d %d\n",sum[i][0],sum[i][1],sum[i][2]);
return 0;
}