传送门:洛谷 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;
}