http://poj.org/problem?id=3784
题意。
多组数据,对于每组数据
输入若干个数,对第k个输入,如果k为奇数,则输出前k个数的中位数
那么这就是动态求中位数了
实现的思路也比较简洁
和这题类似:http://blog.csdn.net/huzujun/article/details/49470135
都是用到双堆的思想
用两个堆, 大顶堆和小顶堆
每次输入一个数,如果这个数比当前的中位数大,就存入小顶堆中, 否则就存入大顶堆。
然后调整, 小顶堆元素的个数要等于大顶堆的元素个数,或者比其多1。
如果小顶堆的元素太多,就塞到大顶堆里,反之亦然
这样一来就会发现。小顶堆的元素比所有大顶堆的元素都大, 而且小顶堆的堆顶就是中位数。
代码还是借用priority_queue 来实现堆
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
priority_queue<int> qmax;
priority_queue<int, vector<int>, greater<int> > qmin;
vector<int> ans;
void add(int x){
if (qmin.empty()){
qmin.push(x);
return;
}
if (x>qmin.top()) qmin.push(x);
else qmax.push(x);
while (qmin.size()<qmax.size()){
qmin.push(qmax.top());
qmax.pop();
}
while (qmin.size()>qmax.size()+1){
qmax.push(qmin.top());
qmin.pop();
}
}
int main()
{
int T;
scanf("%d", &T);
while (T--)
{
while (!qmax.empty()) qmax.pop();
while (!qmin.empty()) qmin.pop();
int p, n;
scanf("%d%d", &p, &n);
ans.clear();
for (int i=1; i<=n; i++){
int x;
scanf("%d", &x);
add(x);
if (i%2==1) ans.push_back(qmin.top());
}
printf("%d %d\n", p, (n+1)/2);
for (int i=0; i<ans.size(); i++){
if (i>0 && i%10==0) puts("");
if (i%10) printf(" ");
printf("%d", ans[i]);
}
printf("\n");
}
return 0;
}