码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2019-07-09 13:46:41      阅读:66      评论:0      收藏:0      [点我收藏+]

标签:n+1   实现   需要   c++   取出   com   ==   pac   算法   

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字符串 题解

标签:n+1   实现   需要   c++   取出   com   ==   pac   算法   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!