CF140C New Year Snowmen

博客食用更佳bossbaby's blog

思路

贪心

首先贪心是很容易想到的,每次取出r个数相同最多的三个
凑成雪人,保存到输出

对于r我们可以用堆来维护,按个数降序排序

离散化(可选)

对于r进行离散化处理,方便push到堆中

代码

#include<bits/stdc++.h>
#define N 100010
#define ll long long
#define work(x) x=q.top();q.pop();x.first--
#define pushh(x) if(x.first)q.push(x)
using namespace std;
struct Ans{
    int a,b,c;
    void put(int x,int y,int z){a=x,b=y,c=z;}
}ans[N];//输出
bool cmp(pair<int,ll>x,pair<int,ll>y){
    return x.second>y.second;
}//输出时的排序
map<ll,pair<int,ll> >m;//用map离散化
priority_queue<pair<int,ll> >q;//大根堆
ll n,cnt;
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        ll x;
        cin>>x;
        m[x].second=x,m[x].first++;
    }//读入并离散化,避免类似基数排序的统计带来的不必要的空间消耗
    for(map<ll,pair<int,ll> >::iterator it=m.begin();it!=m.end();it++)q.push(it->second);
    //使用迭代器把map中的所有数据存入堆中
    while(q.size()>=3){
        pair<int,ll>a[3];
        work(a[0]);work(a[1]);work(a[2]);//取出并个数-1
        sort(a,a+3,cmp);//排序
        pushh(a[0]);pushh(a[1]);pushh(a[2]);//存入
        ans[++cnt].put(a[0].second,a[1].second,a[2].second);//存入答案输出
    }
    cout<<cnt<<endl;
    for(int i=1;i<=cnt;i++)cout<<ans[i].a<<" "<<ans[i].b<<" "<<ans[i].c<<"\n";//输出
    return 0;
}
posted @ 2019-05-30 20:13  bossbaby  阅读(151)  评论(0编辑  收藏  举报