POJ 2833 The Average(优先队列)

原题目网址:http://poj.org/problem?id=2833

本题中文翻译:

描述

 在演讲比赛中,当选手完成演讲时,评委将对他的演出进行评分。 工作人员删除最高成绩和最低成绩,并计算其余成绩的平均值作为参赛者的最终成绩。 这是一个简单的问题,因为通常只有几名评委。

让我们考虑一下上面问题的一般形式。 给定n个正整数,删除最大的n1和最小的n2,并计算其余的平均值。

 输入

 输入由几个测试用例组成。 每个测试用例由两行组成。 第一行包含三个整数n1,n2和n(1≤n1,n2≤10,n1 + n2 <n≤5,000,000)由一个空格隔开。 第二行包含n个正整数ai(对于所有ai, 1≤i≤n,1≤ai≤10^8)由一个空格隔开。 最后一个测试用例后面跟着三个零。

 输出

 对于每个测试用例,输出小数点后的平均值,并将其四舍五入为六位数字。

 Sample Input

1 2 5

1 2 3 4 5

4 2 10

2121187 902 485 531 843 582 652 926 220 155

0 0 0

Sample Output

3.500000

562.500000

Hint

This problem has very large input data. scanf and printf are recommended for C++ I/O.(不要用cin或cout)

The memory limit might not allow you to store everything in the memory.

(本题无法让你一次性输入整个序列,空间不允许)

解题思路:

先输入n1+n2个数,将这些数排序,分别将最小的n2个放到大根堆里,将最大的n1个放到小根堆里。

每读入一个元素,如果当前元素比大根堆堆顶小,说明堆顶一定参与计算,则将堆顶弹出,将当前元素推进去;如果当前元素比小根堆堆顶大,说明堆顶一定参与计算,则将堆顶弹出,将当前元素推进去;(感性理解一下)

如果不符合上面两项条件,则说明当前元素一定参与计算。

AC代码:

 1 #include<cstdio>
 2 #include<queue>
 3 #include<algorithm>
 4 
 5 using namespace std;
 6 
 7 priority_queue<int > a;//大根堆 
 8 priority_queue<int ,vector<int> ,greater<int> > a1;//小根堆 
 9 int n,n1,n2,k,ll[21];
10 long long ans;
11 double ans1;
12 
13 int main() {
14     while(scanf("%d%d%d", &n1, &n2, &n) == 3 && n1 && n2 && n) {
15         while (!a.empty()) a.pop();//初始化一定要记得 
16         while (!a1.empty()) a1.pop();//初始化一定要记得
17         ans = ans1 = 0;//初始化一定要记得
18         for(int i = 1;i <= n1 + n2; i++)
19             scanf("%d",&ll[i]);
20         sort(ll+1,ll+n1+n2+1);
21         for(int i = 1;i <= n2; i++)
22             a.push(ll[i]);
23         for(int i = n2 + 1;i <= n2 + n1; i++)
24             a1.push(ll[i]);
25         for(int i = n1+n2+1;i <= n; i++) {
26             scanf("%d",&k);
27             if(k >= a1.top()) {
28                     ans += a1.top();
29                     a1.pop();
30                     a1.push(k);
31                     continue;
32             }
33             if(k <= a.top()) {
34                     ans += a.top();
35                     a.pop();
36                     a.push(k);
37                     continue;
38             }
39             ans += k;
40         }
41         ans1 = ans;
42         printf("%.6f\n",ans1 / (n - n1 -n2));
43     }
44     return 0;
45 }

 

posted @ 2019-04-26 21:49  Mr^Simon  阅读(315)  评论(0编辑  收藏  举报