Codeforces Round #703 Div.2 A B C1 C2 D

完整题单

我终于要补题了,因为我发现稳定过三题还是难.

以后打算把Div.2的千人题都尽力补了.

A

交了一次WA了后发现漏读一个只能从i到i+1的条件,最后写了个模拟,挺费事的,正解是拿前缀和不停地和公式比较.

B

货舱选址问题,熟悉,一发入魂.

C1,C2

止步于此,太弱了.

一开始自作聪明写了个假的二分,完全没有意识到复杂度不对劲,不停地WA.

直接说C2的算法(也能通过C1),先在1~n中找到第二大的数的位置pos,然后看看1~pos中第二大是不是还是pos,如果是说明最大在1~pos-1,否则在pos+1~n,那么分类讨论,二分求解这两个范围.

边界条件就是pos==1,2,n-1,n,而只需要ask()里判断一下就可以了,感觉不是很容易想到.

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;

int n;

int ask(int x, int y) {
    if (x >= y) return -1;
    cout << "? " << x << ' ' << y << endl;
    cout.flush();
    int ret;
    cin >> ret;
    return ret;
}

int main() {
    cin >> n;
    int pos = ask(1, n);
    if(ask(1, pos) == pos){        // on the left
        int l = 1, r = pos - 1;
        while(l < r){
            int mid = l + r + 1 >> 1;
            if(ask(mid, pos) == pos) l = mid;
            else r = mid - 1;
        }
        cout << "! " << l << endl;
    }else{
        int l = pos + 1, r = n;
        while(l < r){
            int mid = l + r >> 1;
            if(ask(pos, mid) == pos) r = mid;
            else l = mid + 1;
        }
        cout << "! " << l << endl;
    }

    return 0;
}
C2

 D

 对于一个有序序列中的一个数,想要知道它是不是中位数,只需要关心不小于他的数和比他小的数的数量.

如果想要一个有序序列的中位数是否不小于于x,只需要看不小于x的数是否达到序列长度的一半.

后者是一个以x为自变量的具有单调性的问题,使用二分答案求解.

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;

int n, k, s[200010];
int pre[200010];

bool check(int x){
    for(int i = 1; i <= n; i++){
        if(s[i] >= x) pre[i] = 1;
        else pre[i] = -1;
        pre[i] += pre[i - 1];
    }

    int small = 0;
    for(int i = k; i <= n; i++){
        small = min(small, pre[i - k]);
        if(pre[i] - small > 0) return true;
    }
    return false;
}

int main() {
    cin >> n >> k;
    for(int i = 1; i <= n; i++) cin >> s[i];

    int l = 1, r = n;
    while(l < r){
        int mid = l + r + 1 >> 1;
        if(check(mid)) l = mid;
        else r = mid - 1;
    }

    cout << l << endl;

    return 0;
}
D

 

最后发现B是中位数,C是二分,D是中位数与二分.

posted @ 2021-02-19 21:28  goverclock  阅读(72)  评论(0编辑  收藏  举报