CodeForces 140C New Year Snowmen

20 篇文章 0 订阅
5 篇文章 0 订阅

C - New Year Snowmen
Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u

Description

As meticulous Gerald sets the table and caring Alexander sends the postcards, Sergey makes snowmen. Each showman should consist of three snowballs: a big one, a medium one and a small one. Sergey's twins help him: they've already made n snowballs with radii equal tor1r2, ..., rn. To make a snowman, one needs any three snowballs whose radii are pairwise different. For example, the balls with radii 1,2 and 3 can be used to make a snowman but 223 or 222 cannot. Help Sergey and his twins to determine what maximum number of snowmen they can make from those snowballs.

Input

The first line contains integer n (1 ≤ n ≤ 105) — the number of snowballs. The next line contains n integers — the balls' radii r1r2, ..., rn (1 ≤ ri ≤ 109). The balls' radii can coincide.

Output

Print on the first line a single number k — the maximum number of the snowmen. Next k lines should contain the snowmen's descriptions. The description of each snowman should consist of three space-separated numbers — the big ball's radius, the medium ball's radius and the small ball's radius. It is allowed to print the snowmen in any order. If there are several solutions, print any of them.

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

题意:给你n个雪球的半径,问你按照3个半径不同的雪球分组最多能分多少,并输出方案数和方案,如果方案有多种,输出,任意一种。

一开始就是简单的去从小开始枚举了,WA了好几发,但是依旧不知道自己是怎么错的,所以去找了网上的数据:

14
1 1 2 2 3 3 4 4 4 4 5 5 5 5

如果看不到这套数据,估计给我一天我还有可能不知道哪里错了呢。其实仔细想想应该想到才是,感觉自己想的还是不够全面,有时候做题也是这样,所以竞赛才会是组队呢。所以应该是从个数最多的球开始一个个取~而不是按照半径简单的从小到大取。

明白了这个就很好说了,直接按照球的个数从大到小排序放入优先队列。每次取前3种,排好序放进答案队列,球的个数需要减一,如果变成0就不必重新进入队列。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <map>
#include <queue>
using namespace std;
struct node
{
    int num;
    int sum;
    bool operator <(const node a)const
    {
        return a.sum>sum;
    }
};
int ans[100005];
map<int,int>ha;
int main()
{
    int n;
    int i;
    scanf("%d",&n);
    int cnt=0,x;
    for(i=0; i<n; ++i)
    {
        scanf("%d",&x);
        ha[x]++;
    }
    map<int,int>::iterator it=ha.begin();
    node p;
    priority_queue<node>q;
    for(;it!=ha.end();it++)
    {
        p.num=it->first;
        p.sum=it->second;
        q.push(p);
    }
    node t1,t2,t3;
    int a[3];
    while(q.size()>=3)
    {
            t1=q.top();
            q.pop();
            a[0]=t1.num;
            t1.sum--;

            t2=q.top();
            q.pop();
            a[1]=t2.num;
            t2.sum--;

            t3=q.top();
            q.pop();
            a[2]=t3.num;
            t3.sum--;
            sort(a,a+3);
            for(i=2;i>=0;--i)ans[cnt++]=a[i];
            if(t1.sum)q.push(t1);
            if(t2.sum)q.push(t2);
            if(t3.sum)q.push(t3);

    }
    printf("%d\n",cnt/3);
    for(i=0;i<cnt;++i)
    {
       if(i%3==2)printf("%d\n",ans[i]);
       else printf("%d ",ans[i]);
    }
    return 0;
}



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值