1. 程式人生 > 其它 >LuoguP4263 [Code+#3]投票統計 題解

LuoguP4263 [Code+#3]投票統計 題解

LuoguP4263 [Code+#3]投票統計 題解

Content

\(t\) 組詢問,每組詢問給定一個長度為 \(n\) 的數列,請將出現次數最多的數按照從小到大的順序輸出,或者這些數在數列中出現的次數都相等。

資料範圍:\(t\) 未知,\(n\leqslant 10^5,a_i\leqslant 10^9\)

Solution

算是比較小清新的排序題。

我們直接用 map 開個桶,統計每個數出現的次數,然後排序看哪些數出現的次數最多,然後將這些數再次從小到大排序後輸出即可,注意特判一下所有數出現的次數都相等的情況。

Code

int t, n, cnt, a[100007];
struct node {
	int id, val;
	bool operator < (const node& s) const {return val > s.val;}
}kk[100007];
map<int, int> vis;

void cle() {
	_for(i, 1, cnt) vis[kk[i].id] = 0, kk[i].id = 0, kk[i].val = 0;
	cnt = 0;
}

int main() {
	getint(t);
	while(t--) {
		cle();
		getint(n);
		_for(i, 1, n) {
			int x;
			getint(x);
			if(!vis[x]) kk[++cnt].id = x, kk[cnt].val++, vis[x] = cnt;
			else kk[vis[x]].val++;
		}
		int flagofallsame = 1;
		_for(i, 2, cnt) if(kk[i].val != kk[i - 1].val) {flagofallsame = 0; break;}
		if(flagofallsame) {puts("-1"); continue;}
		sort(kk + 1, kk + cnt + 1);
		int ans[100007] = {0}, ansnum = 0;
		_for(i, 1, cnt) {if(kk[i].val == kk[1].val) ans[++ansnum] = kk[i].id; else break;}
		sort(ans + 1, ans + ansnum + 1);
		printf("%d\n", ansnum);
		_for(i, 1, ansnum) printf("%d ", ans[i]);
		puts("");
	}
	return 0;
}