CodeForces 140C New Year Snowmen(堆)
题面
题解
因为要保证两两不同,所以不能单纯的开堆来维护,堆维护一个二元组,个数为第一关键字,编号为第二关键字,对于一个相同的颜色,统计一下这个颜色的个数再用堆来维护就好了。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using std::min; using std::max;
using std::sort; using std::swap;
using std::unique; using std::lower_bound;
using std::priority_queue;
typedef long long ll;
template<typename T>
void read(T &x) {
int flag = 1; x = 0; char ch = getchar();
while(ch < '0' || ch > '9') { if(ch == '-') flag = -flag; ch = getchar(); }
while(ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); x *= flag;
}
const int N = 1e5 + 10;
int n, a[N], b[N], zc[N], col[N];
struct Memb { int val, ind; };
struct Ans { int x, y, z; } A[N]; int tot;
inline bool operator < (const Memb &a, const Memb &b) { return a.val < b.val; }
priority_queue<Memb> q;
int main () {
read(n); int m = n;
for(int i = 1; i <= n; ++i)
read(a[i]), b[i] = a[i];
sort(&b[1], &b[m + 1]), m = unique(&b[1], &b[m + 1]) - b - 1;
for(int i = 1; i <= n; ++i) {
int tmp = lower_bound(&b[1], &b[m + 1], a[i]) - b;
zc[tmp] = a[i], a[i] = tmp, ++col[tmp];
}
for(int i = 1; i <= m; ++i)
q.push((Memb){col[i], i});
Memb a_, b_, c_;
while(q.size() >= 3) {
a_ = q.top(); q.pop();
b_ = q.top(); q.pop();
c_ = q.top(); q.pop();
A[++tot] = (Ans){zc[a_.ind], zc[b_.ind], zc[c_.ind]};
if(--a_.val) q.push(a_);
if(--b_.val) q.push(b_);
if(--c_.val) q.push(c_);
}
printf("%d\n", tot);
for(int i = 1; i <= tot; ++i) {
if(A[i].y > A[i].x) swap(A[i].y, A[i].x);
if(A[i].z > A[i].y) swap(A[i].z, A[i].y);
if(A[i].y > A[i].x) swap(A[i].y, A[i].x);
if(A[i].z > A[i].y) swap(A[i].z, A[i].y);
printf("%d %d %d\n", A[i].x, A[i].y, A[i].z);
}
return 0;
}