/*
1、第一次用数组+排序实现类似优先队列,心情有点小激动;原来数据结构是这样用的
2、回顾了一下插入排序,再原来有序的数组的情况下,插入新元素的插入排序(插入排序的活用)
3、这里是用到了插入排序的思想,而非完全的插入排序的步骤;正如二分思想,他是一种思想,不要
停留在一种方法上、一种数据结构上。
4、poj 2833 时间复杂度 O(n*n),超时,因为优先队列是由最小(大)堆实现的,时间复杂度O(n*logn)----正好服务优先队列的要求,保证队首(栈顶)
元素的优先级最高,其他元素的优先级顺序不考虑。
5、再插入排序中,增加二分查找的思想是不是效率高一些呢? —— 比较次数会减少,移动次数还是不会减少,因此还是不如堆排序效率高;还是那句话这是一种思想的升华。
*/
#include <iostream>
#include <cstdio>
using namespace std;
int n,pmax,pmin;
void insert_sort(int *a,const int &maxn)
{
int i,j,tmp;
for(i=1;i<maxn;i++)
{
tmp = *(a+i);
for(j=i-1;j>=0;j--)
{
if(*(a+j) <= tmp)
break;
*(a+j+1) = *(a+j);
}
*(a+j+1) = tmp;
}
}
void insert_sort_min(int *a,const int &key)// 维护最小数组
{
int j;
for(j=pmin-2;j>=0;j--)// 第一个最大的已被替换
{
if(*(a+j) <= key)
break;
*(a+j+1) = *(a+j);
}
*(a+j+1) = key;
}
void insert_sort_max(int *a,const int &key)
{
int j;
for(j=1;j<=pmax;j++)// 第一个最小的已被替换
{
if(*(a+j) >= key)
break;
*(a+j-1) = *(a+j);
}
*(a+j-1) = key;
}
// 结果的输出
void print(int *a,const int &n)
{
int i;
for(i=0;i<n;i++)
printf("%d ",*(a+i));
printf("\n");
}
int main()
{
long long sum;
int i,j,k,tmp,pma[10],pmi[10];
int f1,f2;
while(scanf("%d%d%d",&pmax,&pmin,&n))
{
sum = 0;
j = 0;//记录最大队列的个数
k = 0;//记录最小队列的个数
if(n==0 && pmax==0 && pmin==0)
break;
for(i=0;i<n;i++)
{
scanf("%d",&tmp);
sum += tmp;
if(j<pmax)
{
pma[j++] = tmp;
if(j==pmax)
insert_sort(pma,pmax);
}
else if(pma[0] < tmp)// 用最小的与之相比
{
// if(f1 == 0)
// {
// f1 = 1;
// insert_sort(pma,pmax);
// print(pma,pmax);
// }//是否是第一次,若是整体插入排序
insert_sort_max(pma,tmp);//若不是做单个插入排序
}
if(k<pmin)
{
pmi[k++] = tmp;
if(k==pmin)// 相等后进入一次全排列,之后仅进入下一个else if
insert_sort(pmi,pmin);
}
else if(pmi[pmin-1] > tmp)// 用最大的与之相比
{
insert_sort_min(pmi,tmp);
}
}
for(i=0;i<pmax;i++)
sum -= pma[i];
for(i=0;i<pmin;i++)
sum -= pmi[i];
printf("%.6lf\n",(sum*1.0/(n-pmax-pmin)));
}
return 0;
}//2833