zoukankan      html  css  js  c++  java
  • hdu6383 p1m2(二分答案)

    p1m2

    题目传送门

    解题思路

    因为x都是非负数,且每一次操作其实就是把总和减少了1,所以可以得出最后都可以到达稳定。最后稳定的数的下界是0,最大也不会超过其初始数的最大值,所以可以用二分答案来求解。每次二分,我们统计要到达出来的二分值,每个数进行上升操作的次数总和以及下降次数的总和。如果上升次数大于下降次数,说明这个答案偏大了则r=mid-1,如果上升次数小于下降次数,由于答案是要求稳定后的最小值,而我们计算是使所有数都变得一样,所以下降次数其实是可以大于上升次数的,所以此时和相等时一样,都是使l=mid;

    代码如下

    #include <bits/stdc++.h>
    #define INF 0x3f3f3f3f
    using namespace std;
    typedef long long ll;
    
    inline int read(){
        int res = 0, w = 0; char ch = 0;
        while(!isdigit(ch)){
            w |= ch == '-', ch = getchar();
        }
        while(isdigit(ch)){
            res = (res << 3) + (res << 1) + (ch ^ 48);
            ch = getchar();
        }
        return w ? -res : res;
    }
    
    const int N = 300005;
    
    int x[N];
    int n;
    
    bool work(int k)
    {
        ll l = 0, r = 0;
        for(int i = 1; i <= n; i ++){
            if(x[i] < k)
                r += k - x[i];
            else {
                l += (x[i] - k + 1) / 2;
                r += (x[i] - k) % 2;
            }
        }
        return l >= r;
    }
    
    int main()
    {
        int t;
        cin >> t;
        while(t --){
            n = read();
            int l = 0, r = 0;
            for(int i = 1; i <= n; i ++)
                x[i] = read(), r = max(r, x[i]);
            int mid = (l + r + 1) / 2;
            while(l < r){
                if(work(mid))
                    l = mid;
                else
                    r = mid - 1;
                mid = (l + r + 1) / 2;
            }
            printf("%d
    ", mid);
        }
        return 0;
    }
    
  • 相关阅读:
    设计模式七大原则之单一职责原则
    机器学习入门与进阶
    Django之路
    Python编程之路
    Python练习1
    Docker入门与进阶
    运维相关
    Node.js(一)
    位运算
    双指针算法
  • 原文地址:https://www.cnblogs.com/whisperlzw/p/11211701.html
Copyright © 2011-2022 走看看