The Preliminary Contest for ICPC Asia Shenyang 2019 F. Honk's pool

题目链接:https://nanti.jisuanke.com/t/41406

思路:如果k的天数足够大,那么所有水池一定会趋于两种情况:

① 所有水池都是一样的水位,即平均水位

② 最高水位的水池和最低水位的水池高度只相差一个高度,且最低水位一定是平均水位

如果k给了个限制:

我们当然需要先算出所有水池高度的平均值。

然后从低到高排序,二分小于平均值的水位,二分高于平均值的水位,

然后判断二分的预期值需要的天数是否小于等于k。然后二分找出最低水位的最大值,

最高水位的最小值,两者相减就是答案了。


 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <cstdio>
 5 #include <map>
 6 #define rep(i,j,k) for(int i = (j); i <= (k); ++i)
 7 #define per(i,j,k) for(int i = (j); i >= (k); --i)
 8 #define rep__(i,j,k) for(int i = (j); i < (k); ++i)
 9 #define per__(i,j,k) for(int i = (j); i > (k); --i)
10 #define inf 1e9
11 using namespace std;
12 typedef long long LL;
13 const int N = 500010;
14 
15 int arr[N],k,n;
16 LL sum,ave;
17 
18 bool check(int mid,int choice){
19     int sum = 0;
20     if(choice == 1){ //大于平均值的
21         rep(i,1,n){
22             if(arr[i] >= mid) break;
23             sum += (mid - arr[i]);
24         }
25     }
26     else{ //小于平均值的
27         per(i,n,1){
28             if(arr[i] <= mid) break;
29             sum += (arr[i] - mid);
30         }
31     }
32 
33     if(sum <= k) return true;
34     else return false;
35 }
36 
37 int main(){
38 
39     while(~scanf("%d",&n)){
40         sum = 0;
41         scanf("%d",&k);
42         rep(i,1,n){
43             scanf("%d",arr + i);
44             sum += arr[i];
45         }
46         
47         sort(arr + 1,arr + 1 + n);
48         ave = sum / n;
49 
50         int l_end,r_start; //低于平均值的最大水位,高于平均值的最小水位
51         l_end = ave;
52         sum % n == 0 ? r_start = ave : r_start = ave + 1; //是否能平分
53         
54         int ans_1,ans_2;
55         int l = arr[1];//左边界
56         int r = l_end;//右边界
57         int mid;
58         while(l <= r){
59             mid = (l + r) >> 1;
60             if(check(mid,1)){
61                 ans_1 = mid;
62                 l = mid + 1;
63             }
64             else r = mid - 1;
65         }
66 
67         l = r_start;//左边界
68         r = arr[n];//右边界
69         while(l <= r){
70             mid = (l + r) >> 1;
71             if(check(mid,2)){
72                 ans_2 = mid;
73                 r = mid - 1;
74             }
75             else l = mid + 1;
76         }
77 
78         printf("%d\n",ans_2 - ans_1);
79     }
80 
81     getchar();getchar();
82     return 0;
83 }

 

posted @ 2019-09-24 20:31  SummerMingQAQ  阅读(242)  评论(0编辑  收藏  举报