一、题目
New Year Snowmen:传送门
Examples
Input
7
1 2 3 4 5 6 7
Output
2
3 2 1
6 5 4
Input
3
2 2 3
Output
0
二、解题步骤
1.题意
有 n 个雪球,给出每个雪球的大小,已知只有三个大小不同的雪球才能堆成一个雪人,问最多能堆几个
2.思路
贪心,由于只有三个大小不同的雪球才能堆成一个雪人,因此应该先拿个数多的雪球,这样等拿完后可以尽量保证剩下的不同大小的雪球最多
实现:
由于 n 最大到 1E9,故用map来统计每种数字出现的次数。
此外,由于要保证每次取的都是个数最多的三个,取完后个数要减一,因此使用优先队列按个数排序;取完后将这三个数字的数量自减1,再进行重复的操作;直到剩下的数字不足三个;
Source Program
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<cmath>
#include<map>
#include<queue>
#include<algorithm>
using namespace std;
typedef long long ll;
#define PII pair<int, int>
const int N = 1e5 + 10;
int t, n, m;
map<int, int>mp;
priority_queue<PII,vector<PII>>q;
int ans[N][3], idx;
bool cmp(PII a, PII b)
{
return a.second > b.second;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin >> n;
for (int i = 1; i <= n; i++)
{
int x; cin >> x;
mp[x]++;
}
for (auto& it : mp)
q.push(make_pair(it.second, it.first));//大根堆中pair<>按第一关键字排序
//<个数,数值>
while (q.size() >= 3)
{
PII p[3];
for (int i = 0; i < 3; i++)
{
p[i] = q.top();
q.pop();
p[i].first--;//取出一个,个数减一
}
for (int i = 0; i < 3; i++)if (p[i].first)q.push(p[i]);//减一若剩余则放回(按第一关键字排序)(贪心)
sort(p,p+3,cmp);//取出的p[3]是按个数排序的,需要重新按值排序(题目要求)
idx++;
for (int i = 0; i < 3; i++)ans[idx][i] = p[i].second;
}
cout << idx << endl;
for (int i = 1; i <= idx; i++)
cout << ans[i][0] << " " << ans[i][1] << " " << ans[i][2] << endl;
return 0;
}