CodeForces 140C New Year Snowmen(堆)

题面

CodeForces

题解

因为要保证两两不同,所以不能单纯的开堆来维护,堆维护一个二元组,个数为第一关键字,编号为第二关键字,对于一个相同的颜色,统计一下这个颜色的个数再用堆来维护就好了。

#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;
}
posted @ 2019-02-03 17:08  water_mi  阅读(183)  评论(0编辑  收藏  举报