zoukankan      html  css  js  c++  java
  • 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
    ",ans_2 - ans_1);
    79     }
    80 
    81     getchar();getchar();
    82     return 0;
    83 }
  • 相关阅读:
    android 混淆代码 -- 报错:can't find referenced class
    adb shell 删除删除指定文件夹和文件
    php GD库
    javascript的继承实现
    Mysql
    如何使用canvas画星星
    基于形态编程设计类
    算法
    腾讯web前端一面
    如何去克服害怕
  • 原文地址:https://www.cnblogs.com/SSummerZzz/p/11580811.html
Copyright © 2011-2022 走看看