B3920 [语言月赛 202401] Genshin 玩家

[语言月赛 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| 1l1r1l2r2s,这里 ∣ 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 s50
  • 60 % 60\% 60% 的数据,保证 ∣ s ∣ ≤ 200 |s| \leq 200 s200
  • 100 % 100\% 100% 的数据,保证 1 ≤ ∣ s ∣ ≤ 2000 1 \leq |s| \leq 2000 1s2000 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;
}

代码解释

  1. 首先,我们读取输入的字符串 s s s,并计算其长度 n n n

  2. 定义变量 ans 表示满足条件的子串对的数量,初始化为 0。

  3. 使用两重循环枚举所有可能的子串对 ( 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 1l1s6
    • 内层循环枚举 l 2 l_2 l2,满足 l 1 + 7 ≤ l 2 ≤ ∣ s ∣ − 5 l_1 + 7 \leq l_2 \leq |s| - 5 l1+7l2s5
  4. 对于每个枚举的 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
  5. 对于每个枚举的 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。
  6. 输出 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)。这样可以更高效地解决问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天秀信奥编程培训

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值