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

【在线测评】

相关推荐
帅次几秒前
Android 高级工程师面试参考答案:语言基础与并发
android·面试·职场和发展
memcpy05 分钟前
LeetCode 1202. 交换字符串中的元素【无向图连通分量】中等
算法·leetcode·职场和发展
小成202303202656 分钟前
数据结构(整理常见结构总结到树层级)
java·c语言·数据结构·c++·链表
ximu_polaris6 分钟前
设计模式(C++)-结构型模式-外观模式
c++·设计模式·外观模式
Xiu Yan15 分钟前
Java 转 C++ 系列:STL常用函数
java·开发语言·c++·stl·visual studio
沫璃染墨22 分钟前
C++ std::list 深度解析:迭代器、splice 核心接口与排序效率全解
开发语言·c++
艾莉丝努力练剑23 分钟前
【Linux网络】计算机网络入门:从背景到协议,理解网络通信基础
linux·运维·服务器·c++·学习·计算机网络
艾莉丝努力练剑23 分钟前
【Linux线程】Linux系统多线程(十):线程安全和重入、死锁相关话题
java·linux·运维·服务器·c++·学习·安全
没有天赋那就反复24 分钟前
C++里面引用参数和实参的区别
开发语言·c++·算法
ximu_polaris28 分钟前
设计模式(C++)-创造型模式-建造者模式
c++·设计模式·建造者模式