我是靠谱客的博主 整齐毛巾,最近开发中收集的这篇文章主要介绍【思维题】Codeforce 1217C The Number Of Good Substrings,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

这段时间要沉迷刷题一段时间了,就让CSDN陪我一起吧!

一、题目大意

题目的大致意思是,我们有一个二进制的字符串,并定义满足一下条件的二进制字符串为好串:

  • 该二进制串所表示的十进制数,正好等于该二进制串的位数(可以包含前导零)
    求问给定的二进制字符串中,它有多少个满足好串定义的子串。

二、题目思路以及AC代码

这道题我刚开始的思路是字符串匹配,可以用KMP尝试一下,也是可以做的,但是就是会超时,但答案是没有错误的。

后来无奈,就去网上找解答,发现果然大佬还是大佬。

大致的思路是这样的,我们从左到右扫描字符串,同时记录前导零的个数(因为当二进制长度不够的时候可以用前导零补充),当扫描到1的时候,开始进行匹配,利用后续的字符以及此时具有的前导
零的个数,可以得到当前这个1之后的所有好子串。

我举个例子方便大家理解。

比如我们要计算二进制串 010010111。那么我们从左至右扫描,下标从0开始,则扫描到下标为1的时候停止,此时具有1个前导零。

  • 那么该下标为1的字符可以产生的好子串首先是1,它只需要1个长度,所以不需要前导零补充。
  • 然后是2,它需要两个长度,也不需要前导零补充
  • 然后是4,它需要4个长度,而从下标为1开始到下标为3,长度是3,但是有一个前导零,所以也满足
  • 然后是9,它需要9个长度,但加上前导零总共也就5个长度,所以不满足条件。

有了上述的例子,相信就很好理解了,下面给出AC代码:

#include <iostream>
#include <string>
#include <cstring>
using namespace std;

int main() {

    int T;
    cin >> T;

    while (T--) {
        string s;
        cin >> s;

        int len = s.length();
        int pre = 0;                        // 记录当前的前导零
        int ans = 0;
        for (int i=0;i<len;i++) {
            if (s[i] == '0') pre++;
            else {
                int r = i;                  // 记录遍历到哪里
                int cur = 1;                // 记录当前要匹配的数
                for (int j=1;j<=18;j++) {
                    if (cur <= pre+(r-i+1)) ans++;
                    if (r+1 >= len) break;
                    cur = cur*2 + (s[++r] - '0') ;
                }
                pre = 0;
            }
        }

        cout << ans << endl;
    }

    return 0;
}

如果有问题,欢迎大家指正!!!

最后

以上就是整齐毛巾为你收集整理的【思维题】Codeforce 1217C The Number Of Good Substrings的全部内容,希望文章能够帮你解决【思维题】Codeforce 1217C The Number Of Good Substrings所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(58)

评论列表共有 0 条评论

立即
投稿
返回
顶部