小ho的01串
Description
有一个由0和1组成的字符串,它好长呀——–一望无际
恩,说正题,小ho的数学不太好,虽然是学计算机的但是看见0和1也是很头疼的,
现在他的老师想让他计算出来包含K个1的子串有多少个—–呀,头要炸了!!!
小ho知道你的数学棒棒哒,所以来找你帮忙了。
Input
第一行是一个数K。
第二行是一个字符串str。
0 < |str| ≤ 106
Output
一个数S,代表了满足条件的个数。
样例输入
Sample Input
2
101010
Sample Output
6
题解:
挺有意思的一道题 蒟蒻当时想了好久没想出来果然菜到家
枚举子串中第一个1的位置x,然后找到它后面的第k个1的位置y
对于这个情况子串就有n*m个(n为x前面连续0的个数+1,m为y后面连续0的个数+1)
AC代码
#include <bits/stdc++.h>
using namespace std;
#define CLR(a,b) memset(a,(b),sizeof(a))
#define LL long long
const int N = 1e6+10;
char str[N];
LL arr[N];
int main()
{
int k;
while(~scanf("%d",&k)) {
CLR(str,0);
scanf("%s",str);
LL len = strlen(str);
LL l = 1, r, ans = 0;
LL sum = 0;
arr[0] = -1;
if(k == 0) {
for(LL i = 0; i < len; i++) {
if(str[i] == '1') {
r = i-1;
l = i+1;
sum += r*(r+1)/2;
}
}
r = len - 1;
sum += r*(r+1)/2;
printf("%lld\n",sum); continue;
}
LL zz = 1;
for(LL i = 0; i < len; i++) {
if(str[i] == '1') {
ans++; arr[zz++] = i;
}
if(ans == k+1) {
sum += (arr[l]-arr[l-1])*(arr[zz-1]-arr[zz-2]); l++; ans--;
}
}
if(ans == k) sum += (arr[l]-arr[l-1])*(len-arr[zz-1]);
printf("%lld\n",sum);
}
return 0;
}