[语言月赛 202401] Genshin 玩家
题目描述
在洛谷入门赛/语言月赛出题 QQ 群里,著名洛谷管理员蓝边铅球老师的群名片是『原神玩家』。这个群名片的含义是,蓝边铅球因为沉迷玩原神,在语言月赛出了不少锅。
现在,扶苏给了你一个字符串 s s s,她想请你求出:有多少种方案可以在 s s s 中取出两个子串 s [ l 1 , r 1 ] , s [ l 2 , r 2 ] s[l_1, r_1], s[l_2, r_2] s[l1,r1],s[l2,r2],满足:
- 1 ≤ l 1 ≤ r 1 ≤ l 2 ≤ r 2 ≤ ∣ s ∣ 1 \leq l_1 \leq r_1 \leq l_2 \leq r_2 \leq |s| 1≤l1≤r1≤l2≤r2≤∣s∣,这里 ∣ s ∣ |s| ∣s∣ 表示字符串 s s s 的长度。
- s [ l 1 , r 1 ] s[l_1, r_1] s[l1,r1] 表示由 s s s 的第 l 1 l_1 l1 个字符到第 r 1 r_1 r1 个字符构成的字符串, s [ l 1 , r 1 ] = Genshin s[l_1, r_1] = \texttt{Genshin} s[l1,r1]=Genshin。
- s [ l 2 , r 2 ] s[l_2, r_2] s[l2,r2] 表示由 s s s 的第 l 2 l_2 l2 个字符到第 r 2 r_2 r2 个字符构成的字符串, s [ l 2 , r 2 ] = player s[l_2, r_2] = \texttt{player} s[l2,r2]=player。
两个方案不同,当且仅当两个方案中 l 1 , r 1 , l 2 , r 2 l_1, r_1, l_2, r_2 l1,r1,l2,r2 至少有一个对应不同。
输入格式
输入只有一行,包含一个字符串 s s s。
输出格式
输出一行一个整数表示答案。
样例 #1
样例输入 #1
Genshinplayerplayer
样例输出 #1
2
样例 #2
样例输入 #2
ExpectedIsAGenshinplayerWhoLikesToBeAGenshinplayer
样例输出 #2
3
提示
数据规模与约定
- 对 30 % 30\% 30% 的数据,保证 ∣ s ∣ ≤ 50 |s| \leq 50 ∣s∣≤50。
- 对 60 % 60\% 60% 的数据,保证 ∣ s ∣ ≤ 200 |s| \leq 200 ∣s∣≤200。
- 对 100 % 100\% 100% 的数据,保证 1 ≤ ∣ s ∣ ≤ 2000 1 \leq |s| \leq 2000 1≤∣s∣≤2000, s s s 中仅含大小写英文字母。
方法1
C++代码
#include <iostream>
#include <string>
using namespace std;
int main() {
string s;
cin >> s;
int n = s.length();
int ans = 0;
for (int l1 = 0; l1 < n; l1++) {
if (l1 + 6 < n && s.substr(l1, 7) == "Genshin") {
for (int l2 = l1 + 7; l2 < n; l2++) {
if (l2 + 5 < n && s.substr(l2, 6) == "player") {
ans++;
}
}
}
}
cout << ans << endl;
return 0;
}
代码解释
-
首先,我们读取输入的字符串 s s s,并计算其长度 n n n。
-
定义变量
ans
表示满足条件的子串对的数量,初始化为 0。 -
使用两重循环枚举所有可能的子串对 ( l 1 , l 2 ) (l_1, l_2) (l1,l2)。
- 外层循环枚举 l 1 l_1 l1,满足 1 ≤ l 1 ≤ ∣ s ∣ − 6 1 \leq l_1 \leq |s| - 6 1≤l1≤∣s∣−6。
- 内层循环枚举 l 2 l_2 l2,满足 l 1 + 7 ≤ l 2 ≤ ∣ s ∣ − 5 l_1 + 7 \leq l_2 \leq |s| - 5 l1+7≤l2≤∣s∣−5。
-
对于每个枚举的 l 1 l_1 l1,我们首先检查 s [ l 1 , l 1 + 6 ] s[l_1, l_1+6] s[l1,l1+6] 是否等于 “Genshin”。
- 如果等于 “Genshin”,我们进入内层循环枚举 l 2 l_2 l2。
- 如果不等于 “Genshin”,我们直接进入下一个 l 1 l_1 l1。
-
对于每个枚举的 l 2 l_2 l2,我们检查 s [ l 2 , l 2 + 5 ] s[l_2, l_2+5] s[l2,l2+5] 是否等于 “player”。
- 如果等于 “player”,将
ans
的值加 1。
- 如果等于 “player”,将
-
输出
ans
的值作为答案。
复杂度分析
-
时间复杂度: O ( n 2 ) O(n^2) O(n2),其中 n n n 是字符串 s s s 的长度。我们使用两重循环枚举所有可能的子串对,每重循环的时间复杂度为 O ( n ) O(n) O(n),因此总时间复杂度为 O ( n 2 ) O(n^2) O(n2)。
-
空间复杂度: O ( 1 ) O(1) O(1)。我们只使用了常数级别的额外空间。
输入输出样例
输入:
Genshinplayerplayer
输出:
2
输入:
ExpectedIsAGenshinplayerWhoLikesToBeAGenshinplayer
输出:
3
优化后的解决方案避免了不必要的循环,将时间复杂度降低到了 O ( n 2 ) O(n^2) O(n2)。这样可以更高效地解决问题。