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;
}

原文地址:https://www.cnblogs.com/ocac/p/11156520.html

时间: 2024-11-01 12:57:50

OCAC暑期比赛第三场 H题 01字符串 题解的相关文章

OCAC暑期比赛第三场 G题 汉堡汪 题解

汉堡汪原题链接:http://codeforces.com/problemset/problem/371/C[题目描述]汪老师准备做汉堡给你吃.但是汪老师只会做一种类型的汉堡,汪老师把他叫做一码汉堡.一码汉堡的组成很简单,它只由面包片(用'B'表示).香肠(用'S'表示).起司(用'C'表示)组成.汪老师有一张食谱,是一个字符串,里面标记了一码汉堡的组成.比如,如果食谱是“BBBSSC”的话,那就是说,这个汉堡是:先叠三块面包片,然后再叠两根香肠,最后再叠一片起司.这样这个汉堡就制作完成了.汪老

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

魔法力量原题链接:http://codeforces.com/problemset/problem/670/D1[题目描述]从床上起来之后,爱丽丝决定做饼干.要完成一块饼干的制作,爱丽丝需要 n 种不同的材料.对于第 i 个材料,他需要的数量为 ai .目前爱丽丝有 n 种不同的材料.对于第 i 个材料,爱丽丝拥有的数量为 bi .爱丽丝初始有 k 点魔法值,每次她可以选择消耗一点魔法值,同时生成 n 种材料中的任意一个材料.你的任务是求出爱丽丝最多能够制作多少块饼干.[输入格式]输入的第一行包

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

线上的点原题链接:http://codeforces.com/problemset/problem/251/A[题目描述]一条直线上有 n 个点,他们的坐标分别是 x1,x2,……,xn.没有两个点的坐标相同.你可以从这些点中挑选出三个点,使得三个点的最大距离不超过 d .请求出满足条件的三个点的方案数.[输入格式]输入的第一行包含两个整数 n 和 d (1<=n<=10^5; 1<=d<=10^9).接下来的一行包含 n 个整数 x1,x2,……,xn,分别表示 n 个点的坐标,

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

袋鼠认妈妈原题链接:http://codeforces.com/problemset/problem/372/A[题目描述]有 n 只袋鼠(题目假设他们都是母的),你需要给他们组建成家庭.对于第 i 只袋鼠来说,它的大小用一个数字 Si 来表示.如果第 i 只袋鼠的大小 Si 达到了第 j 只袋鼠的大小 Sj 的两倍(即满足Si>=2*Sj),那么第 i 只袋鼠可以做第 j 只袋鼠的妈妈.并且如果第 i 只袋鼠已经做了另一只袋鼠的妈妈的话,那么她就不能再认妈妈了.一对母女袋鼠 或者 单独的一只袋

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

袋鼠认妈妈(加强版)原题链接:http://codeforces.com/problemset/problem/372/A不过这道题目是一道变形题,在原题的基础上面做了修改,所以这里的标程不能过CF原题.[题目描述]有 n 只袋鼠(题目假设他们都是母的),你需要给他们组建成家庭.对于第 i 只袋鼠来说,它的大小用一个数字 Si 来表示.如果第 i 只袋鼠的大小 Si 达到了第 j 只袋鼠的大小 Sj 的两倍(即满足Si>=2*Sj),那么第 i 只袋鼠可以做第 j 只袋鼠的妈妈.注意这道题目(加

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

聊天室原题链接:http://codeforces.com/problemset/problem/58/A[题目描述]聪聪最近学会了使用Internet.于是他进入了一个聊天室,并决定向大家打一声招呼——说“hello”.但是因为聪聪的手指不是很灵活,所以他在打“hello”的过程中可能会触碰到一些别的键盘.聪聪打了一个字符串 s .对于这个字符串 s ,如果我们能够从 s 中删除一些字符(当然也可以不删除),使得剩下的字符在不交换次序的情况下恰好等于“hello”,那么我们就可以认为聪聪打了“

题解报告(CDUT暑期集训——第三场)

题解报告(CDUT暑期集训--第三场) A - Problem A. Ascending Rating HDU - 6319 思路:单调队列板子题?(但是弱的一批的我还是不会用(有空补上 用的滑动窗口算法 按着题解的从后往前做(ps:菜是原罪 AC代码 #include<stdio.h> #include<iostream> #include<math.h> #include<algorithm> #include<string.h> #incl

2014 HDU多校弟八场H题 【找规律把】

看了解题报告,发现看不懂 QAQ 比较简单的解释是这样的: 可以先暴力下达标,然后会发现当前数 和 上一个数 的差值是一个 固定值, 而且等于当前数与i(第i个数)的商, 于是没有规律的部分暴力解决,有规律的套公式 //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #include <stdio.h> #include <iostream> #include <cstring&g

OCAC暑期比赛第一场 D题 足球比赛中的危险状态 题解

足球比赛中的危险状态原题链接:http://codeforces.com/problemset/problem/96/A[题目描述]灵灵非常喜欢足球.有一天,灵灵正在看一场足球比赛,在看比赛的同时灵灵在纸上写下了每一位运动员当前的位置.为了简化所有运动员的位置的描述,灵灵将其简化成了仅由字符 "0" 和 "1" 描述的一个字符串.每一个 "0" 表示主队的一个运动员,每一个 "1" 表示客队的一个运动员.如果当前的位置中存在连