【HPUOJ 1415】小ho的0 【字符串】

本文介绍了一种计算包含特定数量1的子串的方法,并提供了一个C++实现示例。该算法通过扫描字符串并利用前缀和技巧来高效地找出所有符合条件的子串。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

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

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

输入
第一行是一个数K。

第二行是一个字符串str。

0 < |str| ≤ 106

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

样例输入
2
101010
样例输出
6

代码

#include<bits/stdc++.h>
using namespace std ;
typedef long long LL ;

const int MAXN = 1e6+100;
const int MAXM = 1e5 ;
const int mod  = 1e9+7 ;

char str[MAXN];
int pos[MAXN];
int num[MAXN]={0};

int main(){
    int k;scanf("%d %s",&k,str+1);
    int len=strlen(str+1);
    int ans=0;
    int size=0;int cnt=0;
    for(int i=1;i<=len;i++){
        if(str[i]=='0') { cnt++; num[i]=cnt; }
        else { num[i]=cnt; cnt=0; }
        if(str[i]=='1') pos[++size]=i;
     }
     if(k==0) {
        for(int i=1;i<=size;i++){
            ans+=(num[pos[i]]-1)*num[pos[i]]/2+num[pos[i]];
         }
         ans+=cnt+(cnt-1)*cnt/2;
         printf("%d\n",ans);
         return 0;
     }
     int i,j;
     for(i=k;i<size;i++){
            if(num[pos[i-k+1]]) 
                ans+=num[pos[i-k+1]]*(num[pos[i+1]]+1)+1+(num[pos[i+1]]);
            else if(num[pos[i+1]]) 
                ans+=num[pos[i+1]]*(num[pos[i-k+1]]+1)+1+num[pos[i-k+1]];
            else ans++;
     }
           if(num[pos[i-k+1]]) 
                ans+=num[pos[i-k+1]]*(cnt+1)+1+cnt;
            else if(cnt) 
                ans+=cnt*(num[pos[i-k+1]]+1)+1+num[pos[i-k+1]];
            else ans++;

     printf("%d\n",ans);
    return  0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值