Running Median(动态维护中位数)poj3784

题意 :依次读入一个整数序列,当读到奇数时,输出此时数列的中位数。

分析 :暴力是不可能暴力的了, 可以建立两个二叉堆,一个大根堆,一个小根堆,大小顺序在前面一半(1 ~ N/2)的序列排在大根堆,排在后面一半(N/2+1 ~ N)的序列排在小根堆,序列为奇数时将中位数放在大根堆堆顶。

当目前序列为奇数时 :读入下一个数字时判断是否大于大根堆的堆顶,如果大于堆顶就插入到小根堆,如果小于堆顶就插入到大根堆,再将大根堆的堆顶插入到小根堆内。
当目前序列为偶数时 :读入下一个数时判断是否大于小根堆的堆顶,如果大于小根堆堆顶,则插入小根堆内,再将小根堆堆顶插入大根堆内,如果小于堆顶
则直接插入大根堆内,大根堆堆顶就是中位数。

小根堆priority_queue<int,vector<int>,greater<int> >maxn
大根堆priority_queue<int,vector<int>,less<int> >minn


哭辽qaq,代码里面的清除队列的方法不知道为啥用不了,卡了我好久!!!

网上的方法
在这里插入图片描述


具体代码

#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
/* 
void clean_queue_min(priority_queue<int,vector<int>,greater<int> >&a){
	priority_queue<int,vector<int>,greater<int> >empty;
	swap(a,empty);
}
void clean_queue_max(priority_queue<int,vector<int>,less<int> >&a){
	priority_queue<int,vector<int>,less<int> >empty;
	swap(a,empty);
}
void clean_queue(queue<int>&a){
	queue<int>empty;
	swap(empty,a);
}
*/ 
int main()
{
	int n,m,t;
	priority_queue<int,vector<int>,greater<int> >minn;//С 
	priority_queue<int,vector<int>,less<int> >maxn;//´ó 
	queue<int>ans;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>m>>t;
		cout<<m<<" "<<(t+1)/2<<endl;
		
		int v;
		cin>>v;
		maxn.push(v);
		ans.push(v);
		for(int i=2;i<=t;i++){
			cin>>v;
			if(i%2==1) {
				if(v<minn.top()) maxn.push(v);
				else{
					minn.push(v);
					maxn.push(minn.top());
					minn.pop();
				}
				ans.push(maxn.top());
			}
			if((i%2==0)){
				if(v>maxn.top()) minn.push(v);
				else{
					maxn.push(v);
					minn.push(maxn.top());
					maxn.pop();
				}
			}
		}
		
		for(int i=1;ans.size()!=0;i++){
			cout<<ans.front();
			ans.pop();
			if(i%10==0) cout<<endl;
			else cout<<" ";
		}
		while(!maxn.empty()) maxn.pop();
		while(!minn.empty()) minn.pop();
		while(!ans.empty()) ans.pop(); 
		cout<<endl;
	}
	
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值