一、内容

题意:依次读入一个整数序列,每当已经读入的整数个数为奇数时,输出已读入的整数构成的序列的中位数。

二、思路

  • 用2个堆,一个大根堆,一个小根堆,先放入一个数到小根堆作为第一个中位数,然后每次比较x是否小于小根堆顶,若小于放入大根堆,否则放入小根堆。
  • 我们还要维护小根堆内元素个数比较大于大根堆一个或者等于大根堆。每次输出的中位数就是小根堆的堆顶。

三、代码

#include <cstdio>
#include <queue>
#include <iostream> 
#include <algorithm>
using namespace std;
int num, t, m, no;
priority_queue<int> da;
priority_queue<int, vector<int>, greater<int> > xiao;
int main() {
	scanf("%d", &t);
	while (t--) {
		while (!da.empty()) da.pop();
		while (!xiao.empty()) xiao.pop();	
		scanf("%d%d%d", &no, &m, &num);
		int cnt = 1;
		printf("%d %d\n%d ", no, (m + 1) / 2, num);
		xiao.push(num); 
		for (int i = 2; i <= m; i++) {
			scanf("%d", &num);
			if (num < xiao.top()) {
				da.push(num);
			} else {
				xiao.push(num);
			}
			while (da.size() > xiao.size()) {
				xiao.push(da.top());
				da.pop();
			}
			while (xiao.size() > da.size() + 1) {
				da.push(xiao.top());
				xiao.pop();
			}			
			if (i % 2 == 1) {
				if (cnt++ != 9) {
					printf("%d ", xiao.top());	
				} else {
					cnt = 0;
					printf("%d\n", xiao.top());
				}
			}
		}
 
		if (cnt) puts("");
	}
	return 0;
}