题目描述
程序猿圈子里正在流行一种很新的简写方法:对于一个字符串,只保留首尾字符,将首尾字符之间的所有字符用这部分的长度代替。例如
internationalization
简写成i18n
,Kubernetes
(注意连字符不是字符串的一部分)简写成K8s
,Lanqiao
简写成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
连接起来。详细解析:
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
开始访问字符串中的字符,符合代码中的索引范围要求,即i
和j
都从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 开始的索引)来实现某些逻辑,尤其是在进行计数和累加时。通过在字符串前加一个空格,可以让字符串索引与
i
和j
的索引匹配。例子:
假设
k = 2
,s = "abcabc"
,c1 = 'a'
,c2 = 'c'
:
初始字符串 :
s = "abcabc"
加上空格后的字符串 :
s = " abcabc"
索引就变成了:
css
复制编辑
索引 0 1 2 3 4 5 6 字符 " a b c a b c
这样,
i
从1
开始,对应字符'a'
,j
从k
开始,确保对字符串s
的遍历可以在每个字符间进行有效的比较和计数。总结:
s = " " + s;
的作用是将原始字符串s
的所有字符向后移动一位,并且在最前面添加一个空格字符,这样可以将字符串的索引从0
转换为从1
开始。这种技巧在某些需要 1-based 索引的场景下很常见。