当前位置: 代码迷 >> 综合 >> XDU1283问题 C: Middle Problem
  详细解决方案

XDU1283问题 C: Middle Problem

热度:35   发布时间:2024-01-12 17:19:16.0

1283问题 C: Middle Problem

时间限制: 1 Sec  内存限制: 128 MB

提交: 2802  解决: 405

[提交][状态][讨论版]

题目描述

Glory 是西电著名的 Sugar Daddy, 他会给他的粉丝发糖, 他现在有 n 个粉

, 每个粉丝手里有一定的糖果数量,现在 Glory 又想给他们再发一些糖, 一共

m , 并希望发完糖之后所有粉丝拥有的糖果数量的中位数尽可能地大, 所以

他想问你再给某些人发一些糖之后, 中位数最多能提高到多少。

输入

多组数据,每一组数据第一行两个正整数 n,m, 0 < n 100000, 0 < m < 10^6

接下来一行包含 n 个数,每个数 0 a i 100000 表示标号为 i 的粉丝手里

目前的糖果数量

为了方便计算,所有的 n 都将会是奇数。

输出

对于每一组数据,输出一行包含一个数,表示粉丝拥有糖果数量的中位数在

Glory再次发糖后最高能是多少。

样例输入

3 1

1 1 1

3 2

1 1 1

样例输出

1

2

 

 

ac代码

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<functional> 
using namespace std;
int main(){int m,n;while(scanf("%d %d",&m,&n)!=EOF){int array[m];for(int i=0;i<m;i++){scanf("%d",&array[i]);}sort(array,array+m,less<int>());int kase,k,total=0;for(kase=(m-1)/2,k=kase+1;k<m;k++){total+=(array[k]-array[k-1])*(k-kase);if(n<=total)break;}if(n>total) {printf("%d\n",array[m-1]+(n-total)/(m-kase));continue;}else if(total==n) printf("%d\n",array[k]);else printf("%d\n",array[k-1]+((n-(total-((array[k]-array[k-1])*(k-kase))))/(k-kase)));}return 0;
} 

解释:

粉丝的数量为奇数,这样中位数就是一个数。

下面研究发糖的规律:

 

1)我们先将粉丝手中的糖设成一个数组,然后按升序排列数组,这样我们就知道最中间的那个糖,并且我们只用计算中间及其以后的部分。因为如果发糖到中间前面的部分,不如给直接发到中间及其后面部分更让中位数高,如1235块糖,不给1发只给23发,肯定比都发的中位数高。

 

2)分析情景,粉丝125662块糖,按前面说的不管12,做法:给5要发一块,然后剩下的一块发给6(原来的5),66谁都一样,因为那个变成7的粉丝在最后排序的时候中位数还是6

 

3)分析情景,粉丝125673块糖,有两种做法:一是给567一人发一块,二是给5发两块,给6发一块。显然,二做法更优,这就是代码中的n(糖数)与total(估计数)。估计数的意思是,5要发糖发到要与6齐平,需要一块,这个total=1小于n=3,那么5要与7齐平,需要2+1=3块,刚好。

 

代码实现:

1for(kase=(m-1)/2,k=kase+1;k<m;k++){

total+=(array[k]-array[k-1])*(k-kase);

if(n<=total)break;

}

kase是中位数,k是要与之齐平的数。不管钱前面的,要计算468齐平的估计数的算法:(8-4+8-6),但我们要是468910,就要(10-4)等等吗,显示每次重复计算可能会超时超内存,我们换一种算法:(6-4*1-0+8-4*2-0)等等这样就减少了运算量,设计算法时要考虑到可变性。

 

2if(n>total) {

printf("%d\n",array[m-1]+(n-total)/(m-kase));

continue;

}

n大于total时,中位数与最高数齐平,然后把剩下的n-total平分给中间及其后面的,利用int的取整性刚好解决555再发5块,中位数是5+1,(15/3)。

 

3)等于不说了,

else printf("%d\n",array[k-1]+((n-(total-((array[k]-array[k-1])*(k-kase))))/(k-kase)));

这种情况是n<total,而再往后对齐又小于的情况,k-1for循环后k++,再减去多余的

 

 

 

 

 

 

 

 

sort()函数

环境:#include<algorithm>

#include<functional>

using namespace std;  命名空间

 

 

在标准库中已经有现成的functionalfunctional提供了一堆基于模板的比较函数对象,它们是:equal_to<Type>not_equal_to<Type>greater<Type>greater_equal<Type>less<Type>less_equal<Type>

 

升序:sort(begin,end,less<data-type>()) //这个中英文翻译相反

降序:sort(begin,end,greater<data-type>())

 

#include <iostream>

#include <cstdio>

#include <algorithm>

#include <functional>

using namespace std; //简单使用方法

sort(  A , A+100 , greater<int>()  ); //降序排列

sort(  A , A+100 , less<int>()     ); //升序排列

 


 

  相关解决方案