您的位置:首页 > 其它

CodeForces 165C--字符串(暴力)

2016-07-14 16:08 218 查看
题意:

给一个数字 k (k<1e6)和一个长度不超过(1e6) 的字符串 s ,这个字符串只是由0和1组成,问这个字符串能分成几个满足各字符的和等于

k 的子串?

输入:

1       1010

2       01010

100   01010

输出:

6

4

0

分析:直接暴力,分类讨论,情况一:1的数量小于k,输出0。情况二:k=0,这时只需要统计0的个数即可,由此找到规律,能组成

的子串的数目=((0的个数+1)*0的个数 ) / 2。情况三:也是最重要最难的,找到满足这样规则的最短的子串,然后记录该子串的

两个端点的位置,从开头到该字串的末端可以构成的子串数量=左端点 * 右端点,最后全部遍历一遍字符串就可以了。

代码:

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

const int maxn=1000000+10;
char s[maxn];
int main()
{
int k,i;
long long int sum=0,cur=0,sum2=0;
scanf("%d%s",&k,s);

for(int i=0; i<strlen(s); i++)
{
if(s[i]=='1')
++sum;
}
if(sum<k)
printf("0\n");
if(k==0) ///只统计连续的0,1只做分割
{
long long int sum=0;
long long int cur=0;
for(int i=0; i<strlen(s); i++)
{
if(s[i]=='0')
++cur;
else
{
sum+=(cur)*(cur+1)/2;
cur=0; ///遇到1重置
}
}
sum+=(cur)*(cur+1)/2; ///全是0
printf("%lld\n",sum);
}
long long int left=1,right=0;
for(i=0; i<strlen(s); i++)
{
if(s[i]=='1')
{
left=i+1;
break;
}
}
int pre=0;
cur=0;
for(; i<strlen(s); i++)
{
if(s[i]=='1')
{
++cur;
if(cur>k) ///left从之前right位置开始,临界点
{
right=i-pre;
cur=1;
sum2+=left*right;
left=right;
}
pre=i;
}
}
if(cur==k)
{
right=i-pre;
sum2+=left*right;
}
printf("%lld\n",sum2);
return 0;
}


小结:这个用暴力解决的题目,学的就是一种思路,清晰的思路。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: