poj 2833 The Average

The Average
Time Limit: 6000MS Memory Limit: 10000K
Total Submissions: 9034 Accepted: 2826
Case Time Limit: 4000MS

Description

In a speech contest, when a contestant finishes his speech, the judges will then grade his performance. The staff remove the highest grade and the lowest grade and compute the average of the rest as the contestant’s final grade. This is an easy problem because usually there are only several judges.

在演讲比赛中,当选手发言完毕,评委将根据他们的表现打分。工作人员去掉最高分和最低分,并计算剩下的平均值作为选手的最终成绩。这是一个简单的问题,因为通常只有几个评委。

Let’s consider a generalized form of the problem above. Given n positive integers, remove the greatest n1 ones and the least n2 ones, and compute the average of the rest.

让我们考虑上述问题的一种推广形式。给定n个正整数,去掉N1个最大证书和N2个最小证书,并计算剩下的平均值。

Input

The input consists of several test cases. Each test case consists two lines. The first line contains three integers n1n2 and n (1 ≤ n1n2 ≤ 10, n1 + n2 < n ≤ 5,000,000) separate by a single space. The second line contains n positive integers ai (1 ≤ ai ≤ 108 for all i s.t. 1 ≤ i ≤ n) separated by a single space. The last test case is followed by three zeroes.

输入由若干组测试数据。每组测试数据包括两行。第一行包含三个整数N1,N2和n(1 ≤ n1n2 ≤ 10, n1 + n2 < n ≤ 5,000,000)单独占用一行。第二行包含n个正整数AI(1 ≤ ai ≤ 108 for all i s.t. 1 ≤ i ≤ n)的由一个空格隔开。最后一个测试数据之后是三个零。

Output

For each test case, output the average rounded to six digits after decimal point in a separate line.

对于每组测试数据,在单独的一行输出,并且保留六位小数。

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.

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

上面表示你提交的时候最好用c++

Source


这道题是看完算法导论的堆排序找着做的,于是就维护了两个巨大的堆。。堆的大小就是n1和n2,然后首先要填入n1和n2个值,之后再往堆里面继续添加数据,每添加一次,要做一次堆排,然后就可以直接判断当前数是否大于或者小于堆里面最小,或者最大的数字,之后选择是否添加。
就算如此,依然2800ms,不晓得300ms做法。。。求指教OTZ
下面是代码。。。改了很多次,有些要注意的地方。。。
注意一下因为用c++提交,所以用long long吧
然后浮点运算很费时的,所以最后再转换double吧。。。
#include <stdio.h>
#define PARENT(i)	(i >> 1)
#define LEFT(i)		(i << 1)
#define RIGHT(i)	(i << 1) + 1
int heapsize = 11;

void MAX_HEAPIFY(int a[20], int i);
void MIN_HEAPIFY(int a[20], int i);
void BUILD_MAX_HEAP(int a[20], int n);
void BUILD_MIN_HEAP(int a[20], int n);
void HEAPSORT_MAX(int a[20], int n);
void HEAPSORT_MIN(int a[20], int n);

int main(void ){
	int high[20], low[20];
	int n1, n2, n, num;
	long long sum;
	int i;
	freopen("in", "r", stdin);
	//freopen("out", "w", stdout);

	while(scanf("%d%d%d", &n1, &n2, &n) != EOF && !(n1 == 0 && n2 == 0 && n == 0)){
        //printf("%d%d%d", n1, n2, n);
		sum = 0;
		for (i = 0;i < 20;i ++) high[i] = -1;
		for (i = 0;i < 20;i ++) low[i] = 100000001;


		for (i = 0;i < n;i ++){
			scanf("%d", &num);
			sum += num;
			if (i < n1){
                high[i+1] = num;
                if (i == n1 - 1){
                    BUILD_MAX_HEAP(high, n1);
                    HEAPSORT_MAX(high, n1);
                }
			}else if ((num >= high[1])){
                high[1] = num;
                BUILD_MAX_HEAP(high, n1);
//                printf("high_build:");
//                for (int j = 0;j <= n1 + 2;j ++){
//                    printf("j = %d: %d !", j, high[j]);
//                }
//                printf("\n");
                HEAPSORT_MAX(high, n1);
//                printf("high_sort:");
//                for (int j = 0;j <= n1 + 2;j ++){
//                    printf("j = %d: %d !", j, high[j]);
//                }
//                printf("\n");
			}
			if (i < n2){
                low[i+1] = num;
                if (i == n2 - 1){
                    HEAPSORT_MIN(low, n2);
                }
			}else if ((num <= low[1])){
                low[1] = num;
                HEAPSORT_MIN(low, n2);
            }
		}
//		HEAPSORT_MAX(low, n2+1);
//		HEAPSORT_MIN(high, n1+1);

		for (i = 1;i <= n1;i ++){
			sum -= high[i];
		}
		for (i = 1;i <= n2; i++){
			sum -= low[i];
		}
		printf("%.6f\n", (sum / (double)(n-n1-n2)));
	}
    return 0;
}

void MAX_HEAPIFY(int a[11], int i){
	int l = LEFT(i);
	int r = RIGHT(i);
	int largest;
	int temp;
	if (l <= heapsize && a[l] > a[i]){
		largest = l;
	}else{
		largest = i;
	}
	if (r <= heapsize && a[r] > a[largest]){
		largest = r;
	}
	if (largest != i){
		temp = a[i]; a[i] = a[largest]; a[largest] = temp;
		MAX_HEAPIFY(a, largest);
	}
}

void MIN_HEAPIFY(int a[11], int i){
	int l = LEFT(i);
	int r = RIGHT(i);
	int smallest;
	int temp;
	if (l <= heapsize && a[l] < a[i]){
		smallest = l;
	}else{
		smallest = i;
	}
	if (r <= heapsize && a[r] < a[smallest]){
		smallest= r;
	}
	if (smallest != i){
		temp = a[i]; a[i] = a[smallest]; a[smallest] = temp;
		MIN_HEAPIFY(a, smallest);
	}
}

void BUILD_MAX_HEAP(int a[11], int n){
	int i;
	heapsize = n;

	for (i = (heapsize << 1);i >= 1; i--){
		MAX_HEAPIFY(a, i);
	}
}
void BUILD_MIN_HEAP(int a[11], int n){
	int i;
	heapsize = n;
	for (i = (heapsize << 1);i >= 1;i --){
		MIN_HEAPIFY(a, i);
	}
}
void HEAPSORT_MAX(int a[11], int n){
	int i;
	int temp;
	//BUILD_MAX_HEAP(a, n);
	for (i = n; i >= 2;i --){
		temp = a[i]; a[i] = a[1]; a[1] = temp;
		heapsize--;
		MAX_HEAPIFY(a, 1);
	}
}

void HEAPSORT_MIN(int a[11], int n){
	int i;
	int temp;
	BUILD_MIN_HEAP(a, n);
	for (i = n;i >= 2;i --){
		temp = a[i]; a[i] = a[1]; a[1] = temp;
		heapsize--;
		MIN_HEAPIFY(a, 1);
	}
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值