题目链接: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;
}