Gym - 100989G-(二分)
原题链接:http://codeforces.com/gym/100989/problem/G
There are K hours left before Agent Mahone leaves Amman! Hammouri doesn't like how things are going in the mission and he doesn't want to fail again. Some places have too many students covering them, while other places have only few students.
Whenever Hammouri commands a student to change his place, it takes the student exactly one hour to reach the new place. Hammouri waits until he is sure that the student has arrived to the new place before he issues a new command. Therefore, only one student can change his place in each hour.
Hammouri wants to command the students to change their places such that after Khours, the maximum number of students covering the same place is minimized.
Given the number of students covering each place, your task is to find the maximum number of students covering the same place after K hours, assuming that Hammouri correctly minimizes this number.
Input
The first line of input contains two integers M (2 ≤ M ≤ 105) and K (1 ≤ K ≤ 109), where M is the number of places and K is the number of hours left before Agent Mahone leaves Amman.
The second line contains M non-negative integers, each represents the number of students covering one of the places. Each place is covered by at most 109 students.
Output
Print the maximum number of students covering a place after K hours, assuming that Hammouri minimized this number as much as possible in the last K hours.
Examples
5 4
3 4 1 4 9
5
2 1000000000
1000000000 4
500000002
5 3
2 2 2 2 1
2
题意:首先题目的意思是指,他有K个小时,每次(每个小时)只能移动一个人到一个地方(可以选择不移动),要求K个小时之后,覆盖同一地方的学生的最大数量被最小化(总的来说就是让各个地方人数更加均衡)。
思路:首先我们很容易的知道不管怎么移动,平均数是不变的。min_max(覆盖同一地方的学生的最大数量的最小化)的值是一定>=sum/M的。
个人思路:
1:当时间充足的情况下,我们是可以把(覆盖同一地方的学生的最大数量被最小化)降到最低的,如果sum%M==0,表明每个地方可以均分人数,所以最后min_max=sum/M;
如果sum%M!=0,表明不能均分,那么min_max=sum/M+1;
2:时间不充足,那么只能让数量大的地方先减小。具体方法用二分。
1 #include<stdio.h> 2 #define ll long long 3 ll location[100010]; 4 ll M,K; 5 ll min_max; 6 ll min(ll a,ll b) 7 { 8 if(a>b)return b; 9 return a; 10 } 11 int judgment(ll mid)//判断能不能把比mid大的(地方学生人数)都移到其他地方使其人数减少到mid 12 { 13 ll cnt=0; 14 for(int i=0;i<M;i++) 15 { 16 if(location[i]>mid) 17 { 18 cnt+=location[i]-mid; 19 } 20 } 21 if(cnt>K) 22 return 0; 23 else 24 return 1; 25 } 26 void binary(ll l,ll r) 27 { 28 while(l<=r) 29 { 30 ll mid=(l+r)/2; 31 if(judgment(mid))//如果在规定时间能使人数减少到mid 32 { 33 r=mid-1; 34 min_max=min(min_max,mid);//更新min_max 35 } 36 else 37 { 38 l=mid+1;//如果在规定时间不能使人数减少到mid 39 } 40 } 41 } 42 int main() 43 { 44 while(scanf("%d%d",&M,&K)!=EOF) 45 { 46 min_max=9999999999;//覆盖同一地方的学生的最大数量的最小化 47 int average;//平均数 48 int max=0;//记录未移动前数值最大值为多少 49 long long sum=0; 50 for(int i=0;i<M;i++) 51 { 52 scanf("%lld",&location[i]); 53 sum+=location[i]; 54 if(location[i]>max) 55 max=location[i]; 56 } 57 if(sum%M==0) 58 average=sum/M; 59 else 60 average=sum/M+1;//这里的average指的是均分最优的时候的值,min_max>=average 61 binary(average,max); 62 printf("%lld\n",min_max); 63 } 64 return 0; 65 }