NCS

69 篇文章 0 订阅

NCS


题目描述

某巨魔有条长度为 N 的由红色头骨和绿色头骨组成的项链(当然事实上是没有的),这条项链现在已经断开了。
由于这条项链太长了,巨魔想截取其中一段长度非零的项链作为自己的新项链。
这个巨魔很迷信,它认为截取下来的项链段上如果有正好 M 个红色头骨那么这段项链就可以认为是有利于报复社会的。
它想知道有多少种截取方法使得截下来的项链利于报复社会。
两种截取方法被认为不同当且仅当它们至少有一个截取的位置不同。
当然,巨魔也可以保留这条项链,不截取。


输入格式

第一行一个数字 M
第二行一个01字符串,0 表示绿色头骨, 1 表示红色头骨。该字符串的长度为 N


输出格式

输出一行,即截下来的项链有利于报复社会的截取方案数。


样例输入

1
1010


样例输出

6

样例解释

截取方案:[1,1],[1,2],[2,3],[2,4],[3,4],[3,3]。总共 6 种。


数据范围

10% 的数据: 1N100
30% 的数据: 1N1000
100% 的数据: 1N1000000 0M1000000


Solution

求出前缀和 x[i] 和 前缀和等于 k 的位置的数量 y[k]
则对于前缀和为 x[i] 的位置 i ,以它为右端点的截取方案的个数为 y[mx[i]]
注意考虑 m=0 的情况。


Code

#include <iostream>
#include <cstdio>

#define Min(x,y) ((x)<(y)?(x):(y))

using namespace std;

int m,ans,i;
int w[1000010];
int s[1000010];
int ss[1000010];

int main(){

    freopen("nichs.in","r",stdin);
    freopen("nichs.out","w",stdout);

    scanf("%d",&m);
    ss[0]=1;
    while(scanf("%1d",&w[++i])!=EOF){
        s[i]=s[i-1]+w[i];
        if(s[i]>=m)ans+=ss[s[i]-m];
        if(s[i]==s[i-1])ss[s[i]]++;
        else ss[s[i]]=1;
    }
    printf("%d\n",ans);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值