Educational Codeforces Round 128 (Rated for Div. 2)C. Binary String

这篇博客探讨了如何使用二分查找和双指针策略解决Educational Codeforces Round 128 (Rated for Div. 2)C题——Binary String。博主解释了题目的意思,即在01字符串中删除部分字符以最大化0的个数和被删除的1的个数之和,并提供了详细的思路分析和代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:

给了你一个01字符串,你可以删除字符串的头部若干元素,尾部若干元素(亦可以不删除),现在让你求一个代价,代价是剩余字符串中的0的个数和删除了的字符串中的1的个数的最大值。

思路:

根据题意是让你求最大的最小值,那么这个题就是一个二分,二分+双指针
题目中让我们求成本,那么我们直接对成本进行二分即可,我们需要用两个数组来装0的前缀和和1的前缀和,现在来想一下二分的check函数:
我们二分的是成本,成本要么是删除了的中的1,或者是剩下的0,下面想一下双指针怎么用,这里我们用的是快慢指针,l = 0, r = 1。来看代码

/*
最大值最小
*/

#include <bits/stdc++.h>

using namespace std;

const int N = 2e5 + 10;

int sum1[N], sum0[N];
string s;
int len;

bool check(int ans)
{
    for (int l = 0, r = 1; r <= len; r ++)
    {
    	/*
		首先双指针内的0的数目不能超过ans,因为我们取的最大值就是ans,然后我们要区间的长度尽量的长,这个答案的最大值才可能尽量的小。(说明一下,字符串给定了,说明每个区间内的01的数目是固定了的)
		然后我们在来考虑区间以外的1的数目,1的数目也不能超过ans,如果这段区间以外的1的数目<=ans,说明我们的区间找大了,区间找大了说明二分的答案大了,则return true。
*/
        while (l < r && sum0[r] - sum0[l] > ans) l ++;
        if (sum1[l] + sum1[len] - sum1[r] <= ans) return true;
    }
    return false;
}

void solve()
{
    cin >> s;
    len = s.length();
    s = " " + s;

    for (int i = 1; i <= len; i ++)
    {
        sum0[i] = sum0[i - 1] + ((s[i] - '0') ^ 1);
        sum1[i] = sum1[i - 1]+ (s[i] - '0');
    }

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

    cout << l << endl;
}

int main()
{
    std::ios::sync_with_stdio(false);

    int t; cin >> t;
    while (t --) solve();

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值