1217C。良い部分文字列の数(考える)

バイナリ文字列sを取得します(各文字が0または1の場合、文字列はバイナリであることを思い出してください)。

 

f(t)を整数tの10進数表現とし、バイナリ形式で記述します(先行ゼロが含まれる場合があります)。たとえば、f(011)= 3、f(00101)= 5、f(00001)= 1、(10)= 2、f(000)= 0およびf(000100)= 4。

 

r-l + 1 = f(sl ... sr)の場合、サブストリングsl、sl + 1、...、srが適切です。

 

たとえば、文字列s = 1011には5つの部分文字列があります:s1 ... s1 = 1、s3 ... s3 = 1、s4 ... s4 = 1、s1 ... s2 = 10、s2 ... s4 = 011。

 

あなたの仕事は、文字列s内の適切な部分文字列の数を数えることです。

 

解決策:

値と長さが等しい部分文字列の数を求めます。

この方法では、先行する0の数をリアルタイムでカウントし、各数値を開始点として使用して、リアルタイムでバイナリ文字列を生成します。長さの比率が小さく、先行する0の数が2つの差よりも大きい場合は、合法です。

#include <bits / stdc ++。h>
 using  namespace std; 
typedef long  long ll;
const  int maxn = 2e5 + 100 ;
文字列s;
int main(){
     int T; 
    scanf(" %d "、&T);
    while(T-- ){ 
        cin >> s;
        int ans = 0 ;
        int pre = 0 ;
        forint i = 0 ; i <s.length(); i ++){
             if(s [i] == ' 0 '  ++より;
            else {
                 int r = i;
                int cnt = 1 ;
                forint j = 0 ; j < 18 ; j ++ ){
                     if(cnt <= pre +(r-i + 1 ))
                        ans ++ ;
                    if(r == s.length()- 1 ブレーク ;
                    cnt = cnt * 2 +(s [++ r]- ' 0 ' ); 
                } 
                // 前方拡張長さが十分でない場合は、先頭の0 
                pre = 0 ; 
            } 
        } 
        printf(" %d \ n " 、ans)を使用; 
    } 
}

 

おすすめ

転載: www.cnblogs.com/zhanglichen/p/12687500.html