【二分】CF1623 C

Problem - 1623C - Codeforces

题意:

【二分】CF1623 C_第1张图片

【二分】CF1623 C_第2张图片 

思路:

肯定是二分,我们去二分最小值,然后check的时候最小值要大于mid

check的时候要让最小值尽可能大

注意到我们不需要去管最大值,只需要最小值尽可能大就好了,因此倒着考虑,直接把大数减到mid大小,分给前面即可

注意在取d的时候要和原来的取min,我因为没看清题意调了一会,结果发现加了个min就过了

Code:

#include 

#define int long long

using i64 = long long;

constexpr int N = 2e5 + 10;
constexpr int mod = 998244353;

int n;
int a[N], b[N];

bool check(int mid) {
    for (int i = 1; i <= n; i ++) {
        b[i] = a[i];
    }
    for (int i = n; i >= 3; i --) {
        if (b[i] < mid) return false;
        int d = std::min((b[i] - mid) / 3, a[i] / 3);
        if (d > 0) {
            b[i] -= 3 * d;
            b[i - 2] += 2 * d;
            b[i - 1] += d;
        }
    }
    return b[1] >= mid && b[2] >= mid;
}
void solve() {
    std::cin >> n;
    for (int i = 1; i <= n; i ++) {
        std::cin >> a[i];
    }

    int l = 0, r = 1e9;
    int ans = 0;
    
    while(l <= r) {
        int mid = l + r >> 1;
        if (check(mid)) {
            ans = mid;
            l = mid + 1;
        }else {
            r = mid - 1;
        }
    }
    std::cout << ans << "\n";
}
signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    int t = 1;
    std::cin >> t;
    while(t --) {
        solve();
    }
    return 0;
}

你可能感兴趣的:(二分,算法)