题目大意:给一个由0和1组成的字符串,找连续的子串,使这一段子串所代表的十进制数等于长度,求这样的子串的个数。
思路:从头到尾遍历,0,只提供长度,所以只需统计前置0的数量,如果遇到1就将数字就要翻倍或者+1,如果当前的数字已经大于了长度,就将前置0的数量清零,从上一个1的下一位继续遍历。
#include <bits/stdc++.h>
using namespace std;
int n, zero, sum, ans;
char ch;
int main()
{
cin>>n;
while(n--)
{
string s;
cin >> s;
while (ch == '0' || ch == '1')
{
s += ch;
}
ans = 0, zero = 0, sum = 0;
for (int j = 0; j < s.size(); j++)
{
if (s[j] == '0')
{
zero++;//统计前置0的数量
}
else
{
for (int k = j; k < s.size() && k < j + 19; k++)
{//长度不超过2的20次方,所以最多循环20次
sum = sum * 2 + s[k] - '0';//遇到1乘2,再加上当前位置的数字
if (sum >= k - j + 1 && sum <= k - j + 1 + zero)
{
ans++; //如果当前数字在当前的遍历区间和加上前置0的区间内,合法
}
else break;//数字增长大于长度增长,数字大于长度后,结束当前遍历
}
zero = 0, sum = 0;
}
}
cout<<ans<<endl;
}
return 0;
}