中位数最大问题
问题:
Description
Glory 是xd著名的 Sugar Daddy,他会给他的粉丝发糖,他现在有 n 个粉
丝, 每个粉丝手里有一定的数量的糖果,现在 Glory 又想给他们再发一些糖,一
共 m 颗,并希望发完糖之后所有粉丝拥有的糖果数量的中位数尽可能地大,所
以他想问你再给某些人发一些糖之后,中位数最多能提高到多少。
Input
多组数据,每一组数据第一行两个正整数 n,m, 0 < n ≤ 100000; 0 < m < 106
接下来一行包含 n 个数,每个数 0 ≤ ai ≤ 100000 表示标号为 i 的粉丝手里
目前的糖果数量
为了方便计算,所有给出的 n 都将会是奇数。
Output
对于每一组数据,输出一行包含一个数,表示粉丝拥有糖果数量的中位数在
Glory 再次发糖后最高能是多少。
对于给出的这n个数,我们首先应该对这n个数进行从小到大的排序。然后,假设我们能够将中位数最大增加到x。所有比中位数小的数,也就是前n/2个数,都是没有用的。要把中位数增加到x,我们就要把所有比中位数大的数,但是比x小的数的值增加到x。我们通过二分查找,找到第一个大于等于x的数,所有要增加的数,就是k∈[n/2,t)中的所有数,一共有t-n/2个。将这些数字增加到x所需要的糖果的数量是:
S是预先计算的前缀和:
C源码:
1 #include<stdio.h> 2 int binaryFind(int a[],int low,int high,int target){ 3 int mid=(low+high)/2; 4 if(a[mid]>=target && a[mid-1]<target){ 5 return mid; 6 }else if(a[mid]>target){ 7 high=mid-1; 8 return binaryFind(a,low,high,target); 9 }else{ 10 low=mid+1; 11 return binaryFind(a,low,high,target); 12 } 13 if(low>high) 14 return -1; 15 } 16 void computePreSum(int a[],int length,int sum[]){ 17 for(int i=0;i<length;i++){ 18 for(int j=0;j<=i;j++){ 19 sum[i]=a[j]+sum[i]; 20 } 21 } 22 23 } 24 int needNum(int x,int sum[],int n,int t){ 25 //返回将中位数增加到x,所需要的糖果数 26 int r=(t-n/2+1)*x-(sum[t]-sum[n/2-1]) ; 27 return r; 28 } 29 int main(){ 30 int a[7]={1,2,3,4,6,7,8}; 31 //int result=binaryFind(a,0,5,5); 32 int n=7; 33 int sum[5]={0}; 34 int m=3;//糖果的总数 35 int result; 36 computePreSum(a,7,sum);//计算数组a的前缀和,存储在sum数组中 37 int midNum=a[n/2]; 38 int x=midNum; 39 result=binaryFind(a,0,6,x); 40 while(needNum(x,sum,n,result)<=m){ 41 x++; 42 result=binaryFind(a,0,6,x); 43 } 44 printf("%d",x-1); 45 46 47 /*for(int i=0;i<5;i++){ 48 printf("%d ",sum[i]); 49 }*/ 50 // printf("%d",result); 51 }