總結:
C. The Number Of Good Substrings
思路:題目是找字符串中s[l…r]的二進制值等於 r-l+1,找出多少種可能。
比賽的時候我是直接用個數組存l到r的二進制值,最後超出內存了,最近都沒注意這個,上次做dp也是,一維能解決的非得用二維,改。
實際上直接遍歷字符串找1位置進行計算就可以了。
找到1的時候就說明l到r這段子串的值非0,纔可以進行計算。
遍歷字符串暴力計算就可以了,每次計算x是否小於pos-i+1,如果是ans++,不是就跳出循環即可。
#include<bits/stdc++.h>
#define ll unsigned long long
#define R register int
#define inf 0x3f3f3f3f
#define mod 1000000007;
using namespace std;
inline ll read(){
ll s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;
}
void put1(){ puts("YES") ;}
void put2(){ puts("NO") ;}
void put3(){ puts("-1"); }
const int manx=2e5+5;
int main()
{
ll p=read();
while(p--)
{
string s;
cin>>s;
ll ans=0;
ll n=s.size();
for(int i=0;i<n;i++)
{
ll x=s[i]-'0';
if(x==1) ans++; //如果當前爲1,即本身也符合要求
ll pos=i; // 1後面的第一個位置
while(pos<n-1&&x<=pos-i+1)
//pos<n-1是防止字符串越界 當x大於pos-i+1的時候所以就算計算後面的位置也無法滿足條件
{
pos++; //指針後移
x=(x<<1)+s[pos]-'0'; //指針後移 更新x的值 二進制 所以*2
if(x>=1&&x<=pos-i+1) ans++; //如果x>=1纔有可能符合條件
}
while(i<n&&s[i]=='0') i++; //直接找到下一個1的位置
}
cout<<ans<<endl;
}
return 0;
}