Codeforces-1217C-The Number Of Good Substrings(思维+枚举)

Codeforces-1217C-The Number Of Good Substrings

You are given a binary string s (recall that a string is binary if each character is either 0 or 1).

Let f(t) be the decimal representation of integer t written in binary form (possibly with leading zeroes). For example f(011)=3,f(00101)=5,f(00001)=1,f(10)=2,f(000)=0 and f(000100)=4.

The substring sl,sl+1,…,sr is good if r−l+1=f(sl…sr).

For example string s=1011 has 5 good substrings: s1…s1=1, s3…s3=1, s4…s4=1, s1…s2=10 and s2…s4=011.

Your task is to calculate the number of good substrings of string s.

You have to answer t independent queries.

Input
The first line contains one integer t (1≤t≤1000) — the number of queries.

The only line of each query contains string s (1≤|s|≤2⋅105), consisting of only digits 0 and 1.

It is guaranteed that ∑i=1t|si|≤2⋅105.

Output
For each query print one integer — the number of good substrings of string s.

Example
Input
4
0110
0101
00001000
0001000
Output
4
3
4
3

题目大意:

给你一个二进制字符串,问有多少符合r−l+1=f(sl…sr)的字串,即串的长度等于该串表示的二进制串的十进制数。

题目分析:

这个问题我们要从字符串中的“1”出手,找到串中的“1”,记录这个“1”的前导 0 ,从这个“1”开始往后找满足该二进制的长度,只要满足条件,ans ++。这里要注意条件的初始化,前导 0 的初始化。

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <map>
#include <stack>
#include <vector>
#include <queue>
#define maxn 200005
#define INF 0x3f3f3f3f
using namespace std;
 
typedef long long ll;
 
int t;
char s[maxn];

int main()
{
    while(cin >> t)
    {
        while(t --)
        {
            cin >> s;
            int ans = 0;
            int len = strlen(s);
            int z = 0;
            for(int i = 0; i < len; i ++)
            {
                if(s[i] == '0')
                    z ++;
                else
                {
                    int now = i;
                    int temp = 1;
                    for(int j = 0; j < 20; j ++)
                    {
                        if(temp <= z + now - i + 1)
                            ans ++;
                        if(now + 1 >= len)
                            break;
                        now ++;
                        temp = temp * 2 + (s[now] - '0');
                    }
                    z = 0;
                }
            }
            cout << ans << endl;
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值