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;
}
小结:这个用暴力解决的题目,学的就是一种思路,清晰的思路。
给一个数字 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;
}
小结:这个用暴力解决的题目,学的就是一种思路,清晰的思路。
相关文章推荐
- 教你写一个简单的网页(html网页开发入门)
- mysql主从设置
- C语言中自带的头文件(.h)所包含的函数
- POJ - 3070 - Fibonacci (矩阵快速幂)
- ios键盘收起的常见方法
- html 锚点的使用
- mybatis_XML映射配置文件
- 动态判断键盘的高度
- POJ 2761 划分树
- git学习
- Lock与synchronized 的区别
- 绘制CIE1931
- 您可能感兴趣的
- iOS软件逆向思维
- tomcat内存溢出
- 柳永词
- 守护线程
- Redis存储Java对象
- CentOS 平台,使用 httpd 2.2 和 httpd 2.4 部署 web服务器
- 二叉树------二叉查找树的相关内容