CodeForces 165C Another Problem on Strings(组合)

A string is binary, if it consists only of characters "0" and "1".

String v is a substring of string w if it has a non-zero length and can be read starting from some position in string w. For example, string "010" has six substrings: "0", "1", "0", "01", "10", "010". Two substrings are considered different if their positions of occurrence are different. So, if some string occurs multiple times, we should consider it the number of times it occurs.

You are given a binary string s. Your task is to find the number of its substrings, containing exactly k characters "1".

Input

The first line contains the single integer k (0 ≤ k ≤ 106). The second line contains a non-empty binary string s. The length of s does not exceed 106 characters.

Output

Print the single number — the number of substrings of the given string, containing exactly k characters "1".

Please do not use the %lld specifier to read or write 64-bit integers in С++. It is preferred to use the cin, cout streams or the %I64dspecifier.

Sample Input

Input

11010

Output

6

Input

201010

Output

4

Input

10001010

Output

0

Hint

In the first sample the sought substrings are: "1", "1", "10", "01", "10", "010".

In the second sample the sought substrings are: "101", "0101", "1010", "01010".

题意:在一个01字符川中找出 k 个1的子串的个数。

这题写麻烦了,对于 k 不为 0 的情况 设了 4个指针    (start, End) 表示 从start 到 End正好有 k 个 1,pre 是 start前面最近出现1的位置, last是End后面最近出现1的位置,所以 总个数就是 本身一个 + 前面start - pre - 1个 + 后面 last - End - 1个 + (前面) * (后面),然后 pre = start, start往后移动找下一个1,End = last,last往后移动找下一个1 ... 学的之前的尺规法,

对于k = 0的情况,就直接查 连续0的个数

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstring>
 5 using namespace std;
 6 const int Max = 1000000 + 10;
 7 char str[Max];
 8 typedef long long LL;
 9 void K()
10 {
11     int start = 0;
12     LL cnt, sum;
13     cnt = sum = 0;
14     int len = strlen(str);
15     while (start < len)
16     {
17         while (str[start++] == ‘0‘)
18             cnt++;
19         if (cnt % 2)  // 为了防止爆精度,分情况
20             sum += (cnt + 1) / 2 * cnt;
21         else
22             sum += cnt / 2 * (cnt + 1);
23         cnt = 0;
24     }
25     printf("%I64d\n", sum);
26 }
27 int main()
28 {
29     int k;
30     scanf("%d", &k);
31     scanf("%s", str);
32     if (k == 0)
33     {
34         K();
35     }
36     else
37     {
38     int pre, start, End, last, cnt;
39     pre = start = End = last = cnt = 0;
40     int len = strlen(str);
41     while (str[start] != ‘1‘ && start < len)
42         start++;
43     if (start != len)
44         cnt = 1;
45     pre = -1;
46     End = start + 1;
47     while (cnt < k && End < len)
48     {
49         if (str[End] == ‘1‘)
50             cnt++;
51         End++;
52     }
53     last = End;
54     if (cnt == k)
55         End = End - 1;
56     while (str[last] != ‘1‘ && last < len)
57         last++;
58     LL sum = 0;
59     while (End < len)
60     {
61         LL a = start - pre - 1;
62         LL b = last - End - 1;
63         sum += a + b + a * b + 1;
64         pre = start;
65         while (str[++start] != ‘1‘ && start < len);
66
67         End = last;
68         while (str[++last] != ‘1‘ && last < len);
69     }
70     printf("%I64d\n", sum);
71     }
72     return 0;
73 }

时间: 2024-10-12 21:47:36

CodeForces 165C Another Problem on Strings(组合)的相关文章

Codeforces Round #112 (Div. 2) C Another Problem on Strings

题目链接:Codeforces Round #112 (Div. 2) C Another Problem on Strings 题意:给出一个只含0,1的序列,求序列中和为n的子序列有多少个. 思路:预处理出序列的前缀和,然后枚举序列时,记录(vis)该位置之前已有的前缀和,再查询(sum[i]-n)的个数,即以该位置为结束的子序列和为n的个数. 注意:vis数组中0应该始终存在,初始化vis[0]=1(why?,因为sum[i]本身就等于n算一个方法数). 举一反三:类似的就已经可以得到,任

CodeForces 687A NP-Hard Problem

Portal:http://codeforces.com/problemset/problem/687/A 二分图染色 好模板题 有SPJ 值得注意的是,因为C++的奇妙的运算机制 若在vector变量x.size()=0,则x.size()-1会溢出(此处坑了我3h) 这不禁让我想起了文明2里的甘地 1 #include<iostream> 2 #include<algorithm> 3 #include<set> 4 #include<cstdio> 5

codeforces Round 286# problem A. Mr. Kitayuta&#39;s Gift

Mr. Kitayuta has kindly given you a string s consisting of lowercase English letters. You are asked to insert exactly one lowercase English letter into s to make it a palindrome. A palindrome is a string that reads the same forward and backward. For

codeforces 706C Hard problem DP(动态规划)问题

题目链接:http://codeforces.com/problemset/problem/706/C 题目大意:  给定n个字符串, 每个字符串可以颠倒前后位置(第一个字母到最后一个,第二个字母到倒数第二位) 每次颠倒需要花费ci的力气, 要求将所给的n个字符串用最小力气按字典序排列, 输出力气值, 如果无法按字典序排列, 则输出-1 数据范围:2?≤?n?≤?100?000 . ci (0?≤?ci?≤?1e9) 所有字符串总长度不会超过1000000. 解题思路: 这是一道DP题, dp[

[2016-04-13][codeforces][447][B][DZY Loves Strings]

时间:2016-04-13 23:36:46 星期三 题目编号:[2016-04-13][codeforces][447][B][DZY Loves Strings] 题目大意:已知每个字母的权值,给定一个字符串s,问,插入k个字母进入字符串s之和,最多能得到多大的权值 分析:直接往s后面插入k个权值最大的字母 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; char

codeforces 17A Noldbach problem

Noldbach problem time limit per test 2 seconds memory limit per test 64 megabytes input standard input output standard output Nick is interested in prime numbers. Once he read about Goldbach problem. It states that every even integer greater than 2 c

Codeforces Gym 100187D D. Holidays 排列组合

D. Holidays Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100187/problem/D Description Everyone knows that the battle of Endor is just a myth fabled by George Lucas for promotion of his movie. Actually, no battle of Endor has

Codeforces Round#413 Problem A - C

[写在前面感(乱)叹(七)人(八)生(糟)的话] 本想借此机会一口气玩到蓝名,结果,A题写炸(少判了一种情况),C题写炸(辜负了我5分钟狂敲出来的线段树),结果又掉Rating...内心好绝望... Problem#A Carrot Cakes vjudge链接[here] (偷个懒,cf链接就不给了) 题目大意是说,烤面包,给出一段时间内可以考的面包数,建第二个炉子的时间,需要达到的面包数,问建炉子是否合理. 玄学 & 智商题,可能是因为我智商不够,所以在我决定休息的时候被hank掉了...

Codeforces Gym 100342C Problem C. Painting Cottages 转化题意

Problem C. Painting CottagesTime Limit: 2 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100342/attachments Description The new cottage settlement is organized near the capital of Flatland. The construction company that is building the settl