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

猜你喜欢

转载自www.cnblogs.com/water-mi/p/10350680.html