CodeForcescode
由於要保證兩兩不一樣,因此不能單純的開堆來維護,堆維護一個二元組,個數爲第一關鍵字,編號爲第二關鍵字,對於一個相同的顏色,統計一下這個顏色的個數再用堆來維護就行了。get
#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; }