PIPIOJ 1466: PIPI捡垃圾Ⅱ 堆 思维

54 篇文章 0 订阅
8 篇文章 0 订阅

http://pipioj.online/problem.php?id=1466
在这里插入图片描述
思路:利用堆可快速求出中位数(当然诸如 T r e a p Treap Treap之类的数据结构也是可以的),思路就是用大根堆维护最小的 ( n + 1 ) / 2 (n+1)/2 (n+1)/2个元素,用小根堆维护最大的 n / 2 n/2 n/2个元素,那么中位数要么等于大根堆堆顶要么等于两个堆顶之和再除 2 2 2

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;

priority_queue<int,vector<int>,greater<int>> minq;
priority_queue<int,vector<int>,less<int>> maxq;
int n;

int main()
{
    scanf("%d",&n);
    int val,half;
    double ans;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&val);
        maxq.push(val);
        half=(i+1)>>1;
        while(maxq.size()>half)
            minq.push(maxq.top()),maxq.pop();
        while(!minq.empty()&&maxq.top()>minq.top())
        {
            val=maxq.top();
            maxq.pop();
            maxq.push(minq.top());
            minq.pop();
            minq.push(val);
        }
        if(maxq.size()==minq.size())
            ans=(maxq.top()+minq.top())/2.0;
        else
            ans=maxq.top();
        printf("%.20f\n",ans);
    }
    return 0;
}

也可以根据元素的值进行更加细致的讨论:

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;

priority_queue<int,vector<int>,greater<int>> minq;
priority_queue<int,vector<int>,less<int>> maxq;
int n;

int main()
{
    scanf("%d",&n);
    int val;
    double ans;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&val);
        if(maxq.empty())
            maxq.push(val);
        else if(maxq.size()>minq.size())
        {
            if(val<maxq.top())
            {
                minq.push(maxq.top());
                maxq.pop();
                maxq.push(val);
            }
            else
                minq.push(val);
        }
        else
        {
            if(val<=minq.top())
                maxq.push(val);
            else
            {
                maxq.push(minq.top());
                minq.pop();
                minq.push(val);
            }
        }
        if(maxq.size()==minq.size())
            ans=(maxq.top()+minq.top())/2.0;
        else
            ans=maxq.top();
        printf("%.20f\n",ans);
    }
    return 0;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值