第十四届蓝桥杯省赛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;
}

【在线测评】

相关推荐
浅念-5 分钟前
C++ string类
开发语言·c++·经验分享·笔记·学习
寻星探路1 小时前
【前端基础】HTML + CSS + JavaScript 快速入门(三):JS 与 jQuery 实战
java·前端·javascript·css·c++·ai·html
忘梓.2 小时前
解锁动态规划的奥秘:从零到精通的创新思维解析(10)
c++·算法·动态规划·代理模式
羑悻的小杀马特2 小时前
【动态规划篇】欣赏概率论与镜像法融合下,别出心裁探索解答括号序列问题
c++·算法·蓝桥杯·动态规划·镜像·洛谷·空隙法
愚润求学2 小时前
【动态规划】二维的背包问题、似包非包、卡特兰数
c++·算法·leetcode·动态规划
救赎小恶魔2 小时前
C++算法(5)
java·c++·算法
jjjxxxhhh1233 小时前
RSA加密解密代码
开发语言·c++
重生之后端学习3 小时前
236. 二叉树的最近公共祖先
java·数据结构·算法·职场和发展·深度优先
2501_901147833 小时前
有序数组单一元素查找:从通用解法到算法极致优化——兼谈高性能计算基础思路
算法·面试·职场和发展
ShineWinsu3 小时前
对于C++:模版进阶的解析
开发语言·c++·面试·笔试·求职·进阶·模版