LuoguP7259 [COCI2009-2010#3] SORT 题解

Content

请编写一个“频率排序器”。输入一个
长度为 \(n\) 的数列 \(A=\{a_1,a_2,\dots,a_n\}\),要求:

  • 按照每个数的出现次数降序排列。
  • 如果两个数出现次数相同,则谁在数列中出现的位置靠前,排列之后那个书的位置也是靠前的。

数据范围:\(n\in[1,10^3],1\leqslant a_i\leqslant c\leqslant10^9\)

Solution

我们开个 \(\texttt{map}\) 数组 \(vis\) 用来记录某个数是在数列中第几个出现的(如果某个数 \(x\) 没出现则 \(vis_x=0\)),然后再开个结构体存储:

  • 这个数的值。
  • 这个数最先出现的位置。
  • 这个数出现的次数。

边输入就边记录以上信息。但有个例外,如果这个数第一次出现,则在结构体中新开一个元素,记录当前位置为最先出现的位置,出现次数为 \(1\),数的值为当前读入的数的值。

以上信息记录完以后我们就开始排序了,首先按照数的出现次数为第一关键字降序排列,如果次数相同,再按照最先出现的位置为第二关键字排序。排序完之后就可以输出了。

Code

struct node {
	int fi, ti, num;
	bool operator < (const node& tmp) const {
		if(ti != tmp.ti) return ti > tmp.ti;
		return fi < tmp.fi;
	}
}a[1007];
map<int, int> vis;
int n, c, cnt, x[1007];

int main() {
	n = Rint, c = Rint;
	F(i, 1, n) {
		x[i] = Rint;
		if(!vis[x[i]]) {
			a[++cnt] = (node){i, 1, x[i]};
			vis[x[i]] = cnt;
		} else a[vis[x[i]]].ti++;
	}
	sort(a + 1, a + cnt + 1);
	F(i, 1, cnt) F(j, 1, a[i].ti) printf("%d ", a[i].num);
	return 0;
}
posted @ 2021-12-16 14:26  Eason_AC  阅读(39)  评论(0)    收藏  举报