Running Median

POJ

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

分析:建立两个堆,设已经读入i个数,将从小到大第1~i/2个数放入一个大根堆,将从小到大第i/2+1~i个数放入一个小根堆,则中位数就是小根堆的堆顶.然后如果哪个堆数量超额了,就把该堆堆顶放入另外一个堆中即可.

//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
inline int read(){
    int x=0,o=1;char ch=getchar();
    while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    if(ch=='-')o=-1,ch=getchar();
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*o;
}
priority_queue<int>q;//大根堆
priority_queue<int,vector<int>,greater<int> >Q;//小根堆
int main(){
	int n=read();//多组数据
	for(int o=1;o<=n;++o){
		while(q.size())q.pop();
		while(Q.size())Q.pop();//清空操作
		int num=read(),m=read(),sum=0;
		printf("%d %d
",num,(m+1)/2);
		for(int i=1;i<=m;++i){
			int a=read();
			if(i==1||a>=Q.top()){
				Q.push(a);
				if(Q.size()>((i+1)/2)){
					q.push(Q.top());
					Q.pop();
				}
			}
			else{
				q.push(a);
				if(q.size()>(i/2)){
					Q.push(q.top());
					q.pop();
				}
			}
			if(i&1){
				printf("%d ",Q.top());
				++sum;if(sum%10==0)puts("");
			}
		}
		puts("");
	}
    return 0;
}

原文地址:https://www.cnblogs.com/PPXppx/p/11229505.html