Codeforces Round #651 (Div. 2) D. Odd-Even Subsequence(二分)

题目链接:https://codeforces.com/contest/1370/problem/D

题意

给出一个含有 $n$ 个数的数组 $a$,从中选出 $k$ 个数组成子序列 $s$,使得 $min(max(s_1, s_3,       s_5, \ldots), max(s_2, s_4, s_6, \ldots))$ 最小。

题解

二分最小值,分别讨论二分值在奇数下标序列和偶数下标数列中的情况。

如果可以构造某个序列使其中的数都小于等于二分值则说明该二分值可行,设为上界,否则加一设为下界。

代码

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;

int n, k, a[N];

bool check(int x, bool odd_seq) {
    int tot_len = 0;
    for (int i = 0; i < n; i++) {
        if (odd_seq) {
            if (a[i] <= x) {
                ++tot_len;
                odd_seq = false;
            }
        } else {
            ++tot_len;
            odd_seq = true;
        }
    }
    return tot_len >= k;
}

int binsearch() {
    int l = 0, r = 1e9;
    while (l < r) {
        int mid = (l + r) / 2; 
        if (check(mid, true) or check(mid, false))
            r = mid;
        else
            l = mid + 1;
    }
    return l;
}

int main() {
    cin >> n >> k;
    for (int i = 0; i < n; i++)
        cin >> a[i];
    cout << binsearch() << "\n";
}

猜你喜欢

转载自www.cnblogs.com/Kanoon/p/13173407.html