CodeForces 140C 贪心+优先队列

Description

现在来做雪人,每个雪人由三个不同大小的雪球构成:一个大的,一个中等的,一个小的。现在有 n 个雪球半径分别为 r1r2, ..., rn. 为了做雪人,三个雪球的大小必须两两不同。例如,半径分别为 1,2,3 的雪球可以做成雪人,但 2, 2, 3 或 2, 2, 2 不行。现在需要尽可能做更多雪人。

Input

第一行是一个整数 n (1 ≤ n ≤ 105) — 雪球的数量. 接下来有n行整数 — 雪球的半径 r1r2, ..., 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; 
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Marcus-Bao

万水千山总是情,只给五角行不行

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值