set codeforces567D One-Dimensional Battle Ships

题意:有一个长度为n的区间,现在有k个长度为a的东西,放在长度为n的区间上,且这k个东西没有重叠或接触的地方,也就是两两直接至少中间隔了一个空位

现在Bob按顺序选择了许多个点,Bob每选择一个点,Alice都会撒谎说这个点没有被覆盖,问,Bob在选了哪些点后,能确定Alice一定在说谎,也就是,在第几个点的时候,可以确定这个点一定被覆盖了


思路:

ans记录上一次中区间内最多能放多少个长度为a的东西

每次询问一个点t的时候,找到最左边已经查询过的点记为L,和最右边已经查询过的点记为R,这可以用set来维护。

然后算出这[L+1,R-1]里面本身最多能放多少个长度为a的东西,因为我t点必须是空位,先拿ans-solve(L+1,R-1),就得到了如果[1,L-1]和[R+1,n]能放多少个长度为a的东西的数量

然后再加上[L+1,t-1]和[t+1,R-1],也就是将以前的一个连续区间分成两部分以后,分别能放多少个,,这样就更新了ans

以后每次只要比较ans和k的大小关系,,就能得到答案了

#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<string>
#include<iostream>
#include<functional>
#include<algorithm>

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;

const int MX = 2e5 + 5;
const int INF = 0x3f3f3f3f;

int n, k, a, m, t;
int A[MX];

int solve(int L, int R) {
    if(L > R) return 0;
    return (R - L + 2) / (a + 1);
}

int main() {
    //freopen("input.txt", "r", stdin);
    scanf("%d%d%d%d", &n, &k, &a, &m);
    set<int>work;
    work.insert(0);
    work.insert(n+1);

    int ans = -1, sum = solve(1, n);
    for(int i = 1; i <= m; i++) {
        scanf("%d", &A[i]);
    }

    for(int i = 1; i <= m; i++) {
        t = A[i];
        int L = *(--work.lower_bound(t));
        int R = *work.upper_bound(t);
        work.insert(t);

        sum = sum - solve(L + 1, R - 1) + solve(L + 1, t - 1) + solve(t + 1, R - 1);
        if(sum < k) {
            ans = i;
            break;
        }
    }

    printf("%d\n", ans);
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值