Luogu1168中位数

【题目描述】

给出一个长度为N的非负整数序列Ai,对于所有1≤k≤(N+1)/2,输出A1, A3, …, A2k-1的中位数。即前1,3,5,…个数的中位数。
n<=100000

【思路】

第一步:考虑求1~n的中位数,把数组排序最中间的数就是答案.

⇒考虑怎么用堆来维护这个答案.

对于一个长为i的序列,(i为奇数.)

记x表示这个序列的中位数,然后我们用大根堆维护前一半小的数,用小根堆维护后一半小的数,这样序列分为了[1,(i-1)/2]∪[(i+1)/2,i](x放在哪一半都可以)

现在考虑加进去一个数w
让w和前一半大根堆的堆顶元素比较,大放入后半部分小根堆中,反之,放到前半部分大根堆中

维护两个堆大小差在1以内,然后输出大小较大的堆顶的元素,就是中位数

【代码】
#include<cstdio>
#include<queue>
#include<cmath>//abs头文件
using namespace std;
priority_queue<int,vector<int> >q1;
priority_queue<int,vector<int>,greater<int> >q2;
int main(){
    int n,x;
    scanf("%d",&n);
    scanf("%d",&x);
	q1.push(x);
    printf("%d\n",x); 
    for (int i=2;i<=n;i++){
        scanf("%d",&x);
        if (x>q1.top()) q2.push(x);//新加入的x放进去
            else q1.push(x);
        while(abs((int)q1.size()-(int)q2.size())>1){ //维护两个大小差1以内,abs——取绝对值函数
            if (q1.size()>q2.size()){
			    q2.push(q1.top());q1.pop();
			}
            else{
			   q1.push(q2.top());q2.pop();
			}
		}
        if(i%2==1) printf("%d\n",q1.size()>q2.size()?q1.top():q2.top());//输出大小大的那个堆的堆定元素
    }
    return 0;
}

P.S代码实现及评测中的一点小问题,abs在本机可以编译,但是在洛谷上会出现CE情况

这是由于size()函数返回的是无符号整数,所以使用int转换一下即可【卡了很久】

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值