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;
}