第十四届蓝桥杯省赛C++B组G题【子串简写】题解(AC)






题目大意

给定字符串 s s s,字符 a , b a, b a,b,问字符串 s s s 中有多少个 a a a 开头 b b b 结尾的子串。

解题思路

20pts

使用二重循环枚举左端点和右端点,判断是否为 a a a 开头 b b b 结尾的字符串,是则答案加一。

100pts

数据范围较大,我们需要将时间复杂度控制在 O ( n log ⁡ n ) O(n\log n) O(nlogn) 以内。

法一

我们需要找到所有 a a a 开头 b b b 结尾的字符串,那么我们可以对于每个字符 b b b,去看 b b b 的左侧有几个 a a a,那么这些 a ... b a\dots b a...b 就是合法的字符串。统计某个位置的左侧有几个字符 a a a,我们可以使用前缀和算法进行维护。

法二

我们可以去遍历整个字符串,对于每个 a a a 字符的右侧有几个字符 b b b,那么这些 a ... b a \dots b a...b 都是合法的字符串。统计某个位置之后字符 b b b 的个数,可以使用后缀和算法进行维护。

cpp 复制代码
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long LL;

const int N = 5e5 + 10;

int n, m;
string str;
char a, b;
int s[N];

int main()
{
    cin >> m >> str >> a >> b;
    n = str.size();
    str = ' ' + str;
    
    for (int i = n; i; -- i )
        s[i] = s[i + 1] + (str[i] == b);
    
    LL res = 0;
    for (int i = 1; i + m - 1 <= n; ++ i )
        if (str[i] == a)
            res += s[i + m - 1];
    
    cout << res << endl;
    
    return 0;
}

【在线测评】

相关推荐
xuanjiong11 分钟前
纯个人整理,蓝桥杯使用的算法模板day2(0-1背包问题),手打个人理解注释,超全面,且均已验证成功(附带详细手写“模拟流程图”,全网首个
算法·蓝桥杯·动态规划
Zhichao_9729 分钟前
【UE5 C++课程系列笔记】33——商业化Json读写
c++·ue5
你今天刷题了吗?1 小时前
蓝桥杯练习:翻转二叉树
蓝桥杯
云边有个稻草人1 小时前
【C++】第八节—string类(上)——详解+代码示例
开发语言·c++·迭代器·string类·语法糖auto和范围for·string类的常用接口·operator[]
惊鸿一博1 小时前
c++ &&(通用引用)和&(左值引用)区别
开发语言·c++
高 朗2 小时前
2025高频面试设计模型总结篇
设计模式·面试·职场和发展
nuo5342022 小时前
黑马 C++ 学习笔记
c语言·c++·笔记·学习
DARLING Zero two♡2 小时前
C++类间的 “接力棒“ 传递:继承(上)
开发语言·c++·继承·里氏替换原则
会讲英语的码农2 小时前
如何学习C++以及C++的宏观认知
开发语言·c++·学习
想跑步的小弱鸡7 小时前
Leetcode hot 100(day 3)
算法·leetcode·职场和发展