河南省多校连萌(三)【问题 F: 小ho的01串】

来源:互联网 发布:现代通信网络试题 编辑:程序博客网 时间:2024/05/15 04:58

点击打开链接


问题 F: 小ho的01串

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

提交: 148 解决: 59

题目描述

有一个由01组成的字符串,它好长呀--------一望无际

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

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

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

输入

第一行是一个数K

第二行是一个字符串str

0 < |str| ≤ 106

输出

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

样例输入

2101010

样例输出

6



题解:求包含k个1的子串有多少个


枚举子串中第一个1的位置x,然后找到它后面的第k个1的位置y


对于这个情况子串就有n*m个(n为x前面连续0的个数+1,m为y后面连续0的个数+1)


#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#include<queue>#include<list>#include<cmath>#include<vector>using namespace std;const int maxn=1000010;char str[maxn];long long num[maxn];int main(){//  freopen("in1.txt","r",stdin);//  freopen("out1.txt","w",stdout);    long long ans=0,k,cnt=1;    scanf("%lld%s",&k,str);    long long l=1,r,len=strlen(str),temp=0;num[0]=-1;    if(k==0){        l=0;        for(long long i=0;i<len;++i){            if(str[i]=='1'){                r=i-l;l=i+1;                ans=ans+r*(r+1)/2;                //cout<<ans<<endl;            }        }        r=(len-l);        ans=ans+r*(r+1)/2;        cout<<ans<<endl;        return 0;    }    for(long long i=0;i<len;++i){        if(str[i]=='1'){            temp++;num[cnt++]=i;        }        if(temp==k+1){            ans=ans+(num[l]-num[l-1])*(num[cnt-1]-num[cnt-2]);l++;temp--;            //cout<<num[l]-num[l-1]<<endl;        }    }    if(temp==k){        ans=ans+(num[l]-num[l-1])*(len-num[cnt-1]);    }    cout<<ans<<endl;    return 0;}