P9244 [蓝桥杯 2023 省 B] 子串简写

题目描述

程序猿圈子里正在流行一种很新的简写方法:对于一个字符串,只保留首尾字符,将首尾字符之间的所有字符用这部分的长度代替。例如 internationalization 简写成 i18nKubernetes(注意连字符不是字符串的一部分)简写成 K8sLanqiao 简写成 L5o 等。

在本题中,我们规定长度大于等于 K 的字符串都可以采用这种简写方法(长度小于 K 的字符串不配使用这种简写)。

给定一个字符串 S 和两个字符 c1​ 和 c2​,请你计算 S 有多少个以 c1​ 开头 c2​ 结尾的子串可以采用这种简写?

输入格式

第一行包含一个整数 K。

第二行包含一个字符串 S 和两个字符 c1​ 和 c2​。

输出格式

一个整数代表答案。

输入输出样例

输入 #1复制

复制代码
4
abababdb a b

输出 #1复制

复制代码
6

说明/提示

【样例说明】

符合条件的子串如下所示,中括号内是该子串:

复制代码
[abab]abdb
[ababab]db
[abababdb]
ab[abab]db
ab[ababdb]
abab[abdb]

【评测用例规模与约定】

对于 20% 的数据,2≤K≤∣S∣≤104。

对于 100% 的数据,2≤K≤∣S∣≤5×105。S 只包含小写字母。c1​ 和 c2​ 都是小写字母。

∣S∣ 代表字符串 S 的长度。

蓝桥杯 2023 省赛 B 组 G 题。

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

int k;  // 存储输入的整数 k
string s;  // 存储输入的字符串 s
char c1, c2;  // 存储输入的两个字符 c1 和 c2
typedef long long ll;  // 定义长整型别名 ll
ll cnt = 0, ans = 0;  // cnt 用于记录字符 c1 出现的次数,ans 用于累加最终结果

int main() {
    cin >> k >> s >> c1 >> c2;  // 输入 k, s, c1, c2
    s = " " + s;  // 将字符串 s 前面加上一个空格,调整索引为从 1 开始

    // 遍历字符串 s,i 从 1 到 k,j 从 k 到 s.size()
    for (int i = 1, j = k; j <= s.size(); j++, i++) {
        if (s[i] == c1)  // 如果当前字符等于 c1,增加 cnt
            cnt++;  

        if (s[j] == c2)  // 如果当前字符等于 c2,将 cnt 加到 ans 中
            ans += cnt;  
    }

    cout << ans;  // 输出最终的结果 ans
    return 0;  // 程序结束
}

string s = " " + s; 这一行代码的意思是在字符串 s 的最前面加上一个空格字符 ,即通过字符串连接将一个空格字符 " " 和原来的字符串 s 连接起来。

详细解析:

  1. string s = " " + s;

    • 这里 " " 是一个包含一个空格的字符串,表示一个长度为 1 的字符串。

    • s 是用户输入的字符串。

    • " " + s 这个操作会将 " "s 连接在一起,形成一个新的字符串,原字符串 s 的所有字符都后移一个位置。

    • 然后,这个新字符串被赋值回 s,即 s 的最前面添加了一个空格字符。

为什么要这样做?

这个操作的目的是通过调整字符串的索引 ,使得原来从 1 开始的索引能够在新的字符串中从 1 开始访问。

具体来说:
  • 原始字符串 s 的索引 是从 0 开始的,比如:

    • s[0] 是第一个字符。

    • s[1] 是第二个字符。

  • 经过 s = " " + s; ,字符串的第一个字符会被移到索引 1,而空格字符 " " 会被放到索引 0 处。

这样,原本使用 s[i] 来访问字符的代码,会变成从 1 开始访问字符串中的字符,符合代码中的索引范围要求,即 ij 都从 1 开始。

代码中的作用:

通过将字符串 s 修改为 s = " " + s;,程序实现了从 1 开始遍历字符串 s,而不是从 0 开始。这样,在后续的遍历中,字符 s[i]s[j] 对应的就是我们期望的逻辑中的第 i 和第 j 个字符。

示例:

假设原始字符串 s = "abcabc",经过操作后:

复制代码

cpp

复制编辑

s = " " + "abcabc"; // s becomes " abcabc"

新的字符串 s 将变成:

复制代码

ini

复制编辑

s = " abcabc"

此时,原来的字符串的第一个字符 a 被放置到了索引 1 处,b 在索引 2 处,依此类推。

为什么这样做?

在这个特定的题目中,代码通过使用 1-based index (从 1 开始的索引)来实现某些逻辑,尤其是在进行计数和累加时。通过在字符串前加一个空格,可以让字符串索引与 ij 的索引匹配。

例子:

假设 k = 2, s = "abcabc", c1 = 'a', c2 = 'c'

  1. 初始字符串s = "abcabc"

  2. 加上空格后的字符串s = " abcabc"

索引就变成了:

复制代码

css

复制编辑

索引 0 1 2 3 4 5 6 字符 " a b c a b c

这样,i1 开始,对应字符 'a'jk 开始,确保对字符串 s 的遍历可以在每个字符间进行有效的比较和计数。

总结:

s = " " + s; 的作用是将原始字符串 s 的所有字符向后移动一位,并且在最前面添加一个空格字符,这样可以将字符串的索引从 0 转换为从 1 开始。这种技巧在某些需要 1-based 索引的场景下很常见。

相关推荐
DARLING Zero two♡9 分钟前
C++内存列传之RAII宇宙:智能指针
c++·c++11·智能指针
阿飞__35 分钟前
C++ 使用 ffmpeg 解码本地视频并获取每帧的YUV数据
c++·ffmpeg·音视频
鑫鑫向栄40 分钟前
[蓝桥杯]最优包含
数据结构·c++·算法·职场和发展·蓝桥杯·深度优先
南玖yy42 分钟前
深入理解 x86 汇编中的重复前缀:REP、REPZ/REPE、REPNZ/REPNE(进阶详解版)
开发语言·网络·汇编·后端·算法·bochs
泛舟起晶浪42 分钟前
网络寻路--图论
c++·算法
YKPG1 小时前
C++学习-入门到精通【13】标准库的容器和迭代器
c++·学习·stl
hn小菜鸡1 小时前
LeetCode 3370.仅含置位位的最小整数
算法·leetcode
早日退休!!!1 小时前
C++性能优化指南
开发语言·c++·性能优化
whoarethenext5 小时前
使用 C++/OpenCV 图像直方图比较两个图片相似度
开发语言·c++·opencv·直方图·相似度对比
r0ysue_6 小时前
02.上帝之心算法用GPU计算提速50倍
算法·gpu