OCAC暑期比赛第三场 H题 01字符串 题解

Posted ocac

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OCAC暑期比赛第三场 H题 01字符串 题解相关的知识,希望对你有一定的参考价值。

01字符串
原题链接:http://codeforces.com/problemset/problem/165/C
【题目描述】
一个字符串被称为“01字符串”当且仅当它只包含字符“0”和“1”。
我们从字符串 s 中取出连续的一段组成的非空字符串就是 s 的子串。
比如,"010" 有6个子串:"0", "1", "0", "01", "10", "010"。
一个字符串的两个子串被定义为不同的,当且晋档它们的起始位置或者终止位置不一样就可以了。
给你一个 01字符串 s ,请计算 s 中有多少子串包含了刚好 k 个字符"1"。
【输入格式】
输入的第一行包含一个整数 k (1<=k<=10^6)。
输入的第二行包含一个 01字符串 s, s 的长度不超过 10^6。
【输出格式】
输出一个整数,用于表示 s 的子串中有多少子串包含了刚好 k 个 "1" 。
【样例输入1】
1
1010
【样例输出1】
6
【样例输入2】
2
01010
【样例输出2】
4
【样例输入3】
100
01010
【样例输出3】
0
【样例解释】
在样例1中满足条件的子串有:"1", "1", "10", "01", "10", "010";
在样例2中满足条件的子串有:"101", "0101", "1010", "01010"。
【问题分析】
这道题目存在线性解法,不如双指针。
不过这场比赛主要还是二分专场,所以主要还是讲解二分算法。
首先我们知道,二分问题的求解条件是存在一个单调函数。
所以这里我们需要开一个 sum[] 数组, sum[i] 表示字符串 s[0..i] 中包含了多少个 "1",
基于这个条件,我们就可以进行二分了。
对于以 s[i] 开头的子串,
我们需要二分找到sum[j1]-sum[i-1]>k的最小的元素坐标j1,
以及sum[j2]-sum[i-1]>=k的最大的元素坐标j2(当然如果j2>i,那么我们要将j2赋为i)。
那么以 s[i] 开头包含 k 个 "1" 的子串数量一共有 j1-j2 个。
实现代码如下:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1000100;
int k, n, sum[maxn];
string s;
long long ans;

int get1(int num)     // 大于num的最小元素的坐标,没有则返回n+1
    int L = 1, R = n, res = n+1;
    while (L <= R) 
        int mid = (L + R) / 2;
        if (sum[mid] > num) 
            res = mid;
            R = mid - 1;
        
        else L = mid + 1;
    
    return res;


int get2(int num)     // 大于等于num的最小元素的坐标,没有则返回n+1
    int L = 1, R = n, res = n+1;
    while (L <= R) 
        int mid = (L + R) / 2;
        if (sum[mid] >= num) 
            res = mid;
            R = mid - 1;
        
        else L = mid + 1;
    
    return res;


int main() 
    cin >> k >> s;
    n = s.length();
    for (int i = 1; i <= n; i ++) sum[i] = sum[i-1] + (s[i-1] == ‘1‘);
    for (int i = 1; i <= n; i ++) 
        int j1 = get1(k+sum[i-1]);
        int j2 = get2(k+sum[i-1]);
        if (j2 < i) j2 = i;
        if (j2 < i) continue;
        ans += j1 - j2;
    
    cout << ans << endl;
    return 0;

 

以上是关于OCAC暑期比赛第三场 H题 01字符串 题解的主要内容,如果未能解决你的问题,请参考以下文章

OCAC暑期比赛第三场 E题 线上的点 题解

OCAC暑期比赛第三场 F题 魔法力量 题解

OCAC暑期比赛第三场 I题 袋鼠认妈妈 题解

OCAC暑期比赛第三场 J题 袋鼠认妈妈(加强版) 题解

OCAC暑期比赛第一场 H题 聊天室 题解

OCAC暑期比赛第一场 B题 字符串任务 题解