传送门:洛谷 CF2121B Above the Clouds | Codeforces B. Above the Clouds

更佳的阅读体验:CF2121B 题解


简要题意:给定长度为 $n$ 的只包含小写字母的字符串 $s$,判断是否存在一种分割方式,将 $s$ 分成三个顺序连接的非空子串 $a$, $b$, $c$,使得 $b$ 是字符串 $a + c$ 的子串。

乍一看似乎有点无从下手,于是我们选择先看看样例。于是我们发现,第二和第三组样例的输入:

3
aba
3
aab

输出:

No
Yes

这提示我们,字符串 $b$ 只要有一个字符即可。接下来我们想到,只要 $b$ 的左侧右侧(即 $a$ 或 $c$)包含 $b$ 即可。也就是说,只要 $s_1 \cdots s_{n - 1}$ 之间或 $s_2 \cdots s_n$ 之间有重复的字母即可。

因此我们考虑开一个桶统计出现的字母,如果上述两个区间中的一个满足条件,输出 $\texttt{Yes}$ 即可。

#include <iostream>
using namespace std;

const int N = 30, LIM = 26;
int t, n, cnt[N];
string s;
bool flag;

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    for (cin >> t; t; --t) {
        flag = false;
        cin >> n >> s;
        fill(cnt, cnt + LIM, 0);
        for (int i = 0; i < n - 1; ++i) ++cnt[s[i] - 'a'];
        for (int i = 0; i < LIM; ++i) if (cnt[i] > 1) flag = true;
        fill(cnt, cnt + LIM, 0);
        for (int i = 1; i < n; ++i) ++cnt[s[i] - 'a'];
        for (int i = 0; i < LIM; ++i) if (cnt[i] > 1) flag = true;
        cout << (flag ? "Yes\n" : "No\n");
    } return 0;
}
最后修改:2025 年 06 月 19 日
如果觉得我的文章对你有用,请随意赞赏