POJ 2833 The Average(堆 优先队列)

题目链接:http://poj.org/problem?id=2833

这个题目一看五百万的数据量有点吓人

第一想到是优先队列,瞬间AC

后来自己用队实现个优先队列,后来看题目发现n1和n2都比较小,所以开始连建堆的步骤都省了

直接排序就建队成功了,不过用优先队列和堆运行的时间差不多

手工优先队列:

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;
#define ll long long
int big[200],small[200];
int n,n1,n2;
int pull_big(int root){
    if(root*2>n2) return 0;
    int l,r;
    l=root*2,r=l+1;
    if(big[l]>=big[r] && big[l]>big[root])
    {big[root]^=big[l],big[l]^=big[root],big[root]^=big[l];pull_big(l);}
    else if(big[r]>=big[l]&&big[r]>big[root])
    {big[root]^=big[r],big[r]^=big[root],big[root]^=big[r];pull_big(r);}
    return 0;
}
int pull_small(int root){
    if(root*2>n1) return 0;
    int l,r;
    l=root*2,r=l+1;
    if(small[l]<=small[r] && small[l]<small[root])
    {small[root]^=small[l],small[l]^=small[root],small[root]^=small[l];pull_small(l);}
    else if(small[r]<=small[l] && small[r]<small[root])
    {small[root]^=small[r],small[r]^=small[root],small[root]^=small[r];pull_small(r);}
    return 0;
}
bool cmp1(const int &a,const int &b){
    return a<b;
}
bool cmp2(const int &a,const int &b){
    return a>b;
}
int main(){
    int i,j,k;
    ll ans;
    while(scanf("%d%d%d",&n1,&n2,&n),n+n1+n2){
        ans=0;
        for(i=0;i<100;i++)
        small[i]=2100000000,big[i]=-2100000000;
        for(i=1;i<=n;i++){
            scanf("%d",&k);
            ans+=(ll)k;
            if(i<n2)
            big[i]=k;
            else if(i==n2){
                big[i]=k;
                sort(big+1,big+1+n2,cmp2);
            }
            else{
                if(k<big[1])
                {big[1]=k;pull_big(1);}
            }
            if(i<n1)
            small[i]=k;
            else if(i==n1){
                small[i]=k;
                sort(small+1,small+1+n1,cmp1);
            }
            else{
                if(k>small[1])
                { small[1]=k;pull_small(1);}
            }
        }
        for(i=1;i<=n2;i++)ans-=(ll)big[i];
        for(i=1;i<=n1;i++)ans-=(ll)small[i];
        printf("%lf\n",ans/double(n-n1-n2));
    }
    return 0;
}

STL:

#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h>
#include <queue>
#include <vector>
using namespace std;
#define ll long long
struct mycomp{
    bool operator()(const int &a,const int &b){
        //由小到大排列采用“>”号;如果要由大到小排列,则采用“<”号
        return a>b;
        }
};
priority_queue<int,vector<int>,mycomp>p2;
priority_queue<int>p1;
int n1,n2,n;
int main(){
    int i,j,k;
    ll ans=0;
    while(scanf("%d%d%d",&n1,&n2,&n),n+n1+n2){
        ans=0;
        for(i=0;i<n;i++){
            scanf("%d",&k);
            ans+=(ll)k;
            if(i<n2) p1.push(k);//队顶最大
            else{
                if(k<p1.top())
                p1.pop(),p1.push(k);
            }
            if(i<n1) p2.push(k);//队顶最小
            else{
                if(k>p2.top())
                p2.pop(),p2.push(k);
            }
        }
        while(!p1.empty()){
            //printf("%d ",p1.top());
            ans-=(ll)p1.top();
            p1.pop();
        }
        while(!p2.empty()){
            //printf("%d ",p2.top());
            ans-=(ll)p2.top();
            p2.pop();
        }
        printf("%lf\n",ans/double(n-n1-n2));
    }
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值