您的位置:首页 > 其它

【HPU 1415: 小ho的01串】& 尺取

2017-08-14 17:49 344 查看
1415: 小ho的01串 [字符串]

时间限制: 1 Sec 内存限制: 128 MB

提交: 269 解决: 131 统计

题目描述

有一个由0和1组成的字符串,它好长呀——–一望无际

恩,说正题,小ho的数学不太好,虽然是学计算机的但是看见0和1也是很头疼的,

现在他的老师想让他计算出来包含K个1的子串有多少个—–呀,头要炸了!!!

小ho知道你的数学棒棒哒,所以来找你帮忙了。

输入

第一行是一个数K。

第二行是一个字符串str。

0 < |str| ≤ 106

输出

一个数S,代表了满足条件的个数。

样例输入

2

101010

样例输出

6

来源

Leibniz_Zhang

用数组记录下 1 的下标,维护区间 [l,r] 中 1 的个数为 k,这个区间的贡献等于 (a[l] - a[l - 1] )* (a[r + 1] - a[r]),会出现 010100 的情况在末尾加个 1 即可,k == 0, 相当于求 1 与 1 之间 0 的组合

AC代码:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAX = 1e6 + 10;
typedef long long ll;
int k,a[MAX];
char s[MAX];
void solve(int o){
ll l = 1,r = 0,ans = 0,sum = 0;
a[0] = -1;
for(int i = 0; i <= o; i++)
if(s[i] == '1'){
a[++r] = i,sum++;
if(sum == k + 1) ans += (a[l] - a[l - 1]) * (a[r] - a[r - 1]),l++,sum--;
}
printf("%lld\n",ans);
}
int main()
{
while(~scanf("%d %s",&k,s)){
ll o = strlen(s),l = 0,r = 0,ans = 0;
s[o] = '1';
if(!k){
for(int i = 0; i <= o; i++)
if(s[i] == '1')
r = i - l,l = i + 1,ans += r * (r + 1) / 2;
printf("%lld\n",ans + (r + 1) * r / 2);
}
else solve(o);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数学