Running Median(动态中位数)

18 篇文章 0 订阅

原题链接牛客

原题链接acwing

acwing 的数据量要比牛客少好多可以先写acwing的,牛客的还卡空间。。。。

原题目:

 解题思路:

要求在输入每一个奇数个数时输出中位数,由于是奇数位,中位数的左右个数相同,我们可以用两个优先队列分别记录中位数的左边和右边的数。

可以假设小根堆的队头(左边最大)是中位数,在偶数位的时候,维护以小根堆的队头为中位数时的左右区间(暂不维护左右区间数的个数差),在奇数位的时候,维护左区间的size-右区间的size=1(左区间的最大值是中位数)。

AC代码:

#include <iostream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <algorithm>
#include <vector>
#include <string>
#include <iomanip>
#include <cmath>
#include <ctime>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <unordered_map>
#define Buff std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define ll long long
#define Inf LONG_LONG_MAX
#define inf INT_MAX
#define endl "\n"
using namespace std;
int main(){
Buff;
	int t; cin>>t;
	priority_queue<int> p1;  //左 
	priority_queue<int,vector<int>,greater<int> > p2;  //右 
	while(t--){
		while(!p1.empty()) p1.pop();
		while(!p2.empty()) p2.pop();
		int id,n,a,k=0; cin>>id>>n;
		cout<<id<<" "<<int(n/2)+1<<endl; 
		for(int i=1;i<=n;i++){
			cin>>a;
			if(p1.empty()) p1.push(a);
			else if(a>=p1.top()) p2.push(a);
			else p1.push(a);
			if((i&1)==1){
				while((int)p1.size()-(int)p2.size()>1){
					int s=p1.top();
					p1.pop();
					p2.push(s);
				}
				while((int)p2.size()-(int)p1.size()>-1){
					int s=p2.top();
					p2.pop();
					p1.push(s);
				}
				cout<<p1.top()<<" ";
				k++;
				if(k%10==0) cout<<endl;
			} 
		}
		if(k%10!=0) cout<<endl;
	} 
	return 0;
}

写在后面:

开始的时候为了节省时间把两个优先队列开在了里面(每次重新定义但上次的内存没释放,所以空间会很大。开在外面,每次出队就行了)

这个题的输出格式不喜欢。。。。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

要用bug来打败bug

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值