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 索引的场景下很常见。

相关推荐
ChoSeitaku24 分钟前
NO.71十六届蓝桥杯备战|搜索算法-递归型枚举与回溯剪枝|枚举子集|组合型枚举|枚举排列|全排列问题(C++)
c++·蓝桥杯·剪枝
XYY3691 小时前
搜索与图论 树的广度优先遍历 图中点的层次
算法·图论·宽度优先
Fantasydg4 小时前
DAY 38 leetcode 15--哈希表.三数之和
算法·leetcode·散列表
编程绿豆侠4 小时前
力扣HOT100之链表:19. 删除链表的倒数第 N 个结点
算法·leetcode·链表
ゞ 正在缓冲99%…4 小时前
leetcode274.H指数
java·算法·leetcode
liulun5 小时前
Windows注册鼠标钩子,获取用户选中的文本
c++·windows·qt
柃歌7 小时前
【LeetCode Solutions】LeetCode 136 ~ 140 题解
数据结构·算法·leetcode
杰瑞学AI7 小时前
LeetCode详解之如何一步步优化到最佳解法:21. 合并两个有序链表
数据结构·python·算法·leetcode·链表·面试·职场和发展
石去皿7 小时前
力扣hot100 71-80记录
算法·leetcode·职场和发展
佚明zj7 小时前
[ISP] raw图常见的噪声种类以及生成原因
算法