小ho的01串 [字符串]
时间限制: 1 Sec 内存限制: 128 MB提交: 270 解决: 132 统计
题目描述
有一个由0
和1
组成的字符串,它好长呀--------一望无际
恩,说正题,小ho的数学不太好,虽然是学计算机的但是看见0
和1
也是很头疼的,
现在他的老师想让他计算出来包含K
个1
的子串有多少个-----呀,头要炸了!!!
小ho知道你的数学棒棒哒,所以来找你帮忙了。
输入
第一行是一个数K
。
第二行是一个字符串str
。
0 < |str| ≤ 106
输出
一个数S
,代表了满足条件的个数。
样例输入
2
101010
样例输出
6
题解:这题我的想法是直接用两层for循环直接枚举,(按照理论上来说这里不能用两层for循环,因为字符数组的长度是10的6次方,两层for循环的时间复杂度是O(n^2)很明显是会超时的)
扫描二维码关注公众号,回复:
2717430 查看本文章
下面是两层for的代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
char str[1000005];
int main()
{
int T;
scanf("%d",&T);
int i,j,len,s=0,p=0;
scanf("%s",str);
len = strlen(str);
for(i = 0 ; i < len ; i++ )
{
s=0;
for(j = i ; j < len ; j++)
{
if(str[j]=='1')
s++;
if(s==T)
p++;
if(s>T)
break;
}
}
printf("%d\n",p);
return 0;//这种方法理论上是不对,但是因为后台数据不足,这个也是ac的。
}
下面这个是标准代码:
#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()
{
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;
}
}
r=(len-l);
ans=ans+r*(r+1)/2;
printf("%d\n",ans);
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--;
}
}
if(temp==k)
{
ans=ans+(num[l]-num[l-1])*(len-num[cnt-1]);
}
printf("%d\n",ans);
return 0;
}