• Codeforces Round #352 (Div. 2) D. Robin Hood (二分答案)


    题目链接:http://codeforces.com/contest/672/problem/D

    有n个人,k个操作,每个人有a[i]个物品,每次操作把最富的人那里拿一个物品给最穷的人,问你最后贫富差距有多少。

    先sort一下,最富的人很明显不会低于sum(a1 ~ an) / n , 所以二分一下最富人的最小值 看是否满足操作k。

    最穷的人不会高于sum(a1 ~ an) / n + 1 ,所以二分一下最穷人的最大值 看是否满足操作k。

    (注意一点的是二分以后最穷的人的最大值和最富的人的最小值要是相同,那么要讨论一下总和是否被n整除的情况,要是整除那么差距就为0,否则就为1。)

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int MAXN = 5e5 + 10;
     4 typedef long long LL;
     5 LL a[MAXN], n;
     6 //最穷人的的最大值
     7 bool check_min(LL x, LL k) {
     8     LL cnt = upper_bound(a + 1, a + n + 1, x) - a;
     9     for(int i = 1; i <= cnt - 1; ++i) {
    10         k -= (x - a[i]);
    11         if(k < 0)
    12             return false;
    13     }
    14     return true;
    15 }
    16 
    17 bool check_max(LL x , LL k) {
    18     LL cnt = upper_bound(a + 1, a + n + 1, x) - a;
    19     for(int i = cnt; i <= n; ++i) {
    20         k -= (a[i] - x);
    21         if(k < 0)
    22             return false;
    23     }
    24     return true;
    25 }
    26 
    27 int main()
    28 {
    29     LL k , sum = 0; 
    30     scanf("%lld %lld", &n, &k);
    31     for(int i = 1; i <= n; ++i) {
    32         scanf("%lld", a + i);
    33         sum += a[i];
    34     }
    35     sort(a + 1, a + n + 1);
    36     if(a[1] == a[n]) {
    37         printf("0
    ");
    38         return 0;
    39     }
    40     LL l = a[1], r = sum / n + 1, L = a[1], R = a[n];
    41     while(l < r) { //最穷人的的最大值
    42         LL mid = (l + r) >> 1;
    43         if(check_min(mid, k)) {
    44             l = mid + 1;
    45             L = mid;
    46         }
    47         else
    48             r = mid;
    49     }
    50     l = sum / n, r = a[n];
    51     while(l < r) {
    52         LL mid = (l + r) >> 1;
    53         if(check_max(mid, k)) {
    54             r = mid;
    55             R = r;
    56         }
    57         else
    58             l = mid + 1;
    59     }
    60     printf("%lld
    ", R > L? R - L: (sum % n ? 1 : 0));
    61 }
  • 相关阅读:
    [转载]浅谈多态机制的意义及实现
    [转载]浅析Java虚拟机结构与机制
    为什么调用 FragmentPagerAdapter.notifyDataSetChanged() 并不能更新其 Fragment?
    Android-- FragmentStatePagerAdapter分页
    android-点击空白或点击除EditText之外的控件隐藏软键盘
    populating-next-right-pointers-in-each-node
    roman-to-integer
    same-tree
    palindrome-number
    best-time-to-buy-and-sell-stock
  • 原文地址:https://www.cnblogs.com/Recoder/p/5498243.html
Copyright © 2020-2023  润新知