C. The Number Of Good Substrings

题目:C. The Number Of Good Substrings

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAKuWkp-elug==,size_20,color_FFFFFF,t_70,g_se,x_16

题意:

01字符串中有多少子串满足其十进制数值等于该子串长度,子串可包含前导零算数值。

思路:

注意到字符串S<2e5,而gif.latex?2%5E%7B10%7D=1024,那么gif.latex?2%5E%7B20%7D=1024*1024>1e6,所以我们要计算的一个长度只用20位就足够了,这里我们用一个循环去扫数字1,用p记录它的第一个前导零的位置(也就是上一个计算的串的第一位的下一个),只要当前的计算的串数值小于等于总长度(包括前导零)即可ans++,因为前导零可以补足以达到(长度等于数值的)要求,则退出条件即为数值大于总长度。在代码中,总长度:(j-p+1),i用来扫到数字1作为计算的子串的开头,j往后移的过程中不断判断是否满足条件。同时注意二进制串的值的计算:val=val*2+a[j]-'0';

:p是在两个i(i为1)之间的第一个0的位置,若此时上一个i后面也是1,那么j==p,会在if(val>j-p+1)判断处跳出(因为右边为1,左边由上一行的乘二至少为2)

代码:

#include<stdio.h>
#include<string.h>
int T,n,p,i,j,val,ans;
char a[200005];
int main(){
	scanf("%d",&T);
	while(T--){
		scanf("%s",a);
		n=strlen(a);
		p=ans=0;
		for(i=0;i<n;i++){
			if(a[i]=='1'){
				val=0;
				for(j=i;j<n&&j<=i+20;j++){
					val=val*2+a[j]-'0';//扫到的1以后的十进制值 
					if(val>j-p+1)break;//j-p+1为目前子串(包括前导零)的长度 
					else ans++;//val一定>j-i+1的长度,故只要<长度(括前导零)即可
					            //因为前导零可以匹配 
				}
				p=i+1;//p为下一个可能的串的第一个前导零位置 
			}
		}
		printf("%d\n",ans);
	}
	return 0;
}

 

 

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值