![在这里插入图片描述](https://img-blog.csdnimg.cn/20210226200002937.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0NzkxNDg0,size_16,color_FFFFFF,t_70)
题解
- 我们可以用字典树来查询串中是否出现前缀,对于每个字符串,我们先判断其是不是前面字符串的前缀,或者前面字符串是不是它的前缀,然后再插入即可
- 我们可以将每个字符串的结尾标记,那么每次query的时候,如果当前字符串在原字典树中全部出现,那么这个字符串就是某个字符串的前缀,如果当前字符串从根节点开始向下查询时有一个节点的cnt>0,说明当前这个字符串有前缀存在于字典树中。
代码
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 100010;
int t, n;
char s[10];
int tr[N][10], cnt[N], idx;
void insert(char str[]) {
int p = 0;
for (int i = 0; str[i]; i++) {
int u = str[i] - '0';
if (!tr[p][u]) tr[p][u] = ++idx;
p = tr[p][u];
}
cnt[p]++;
}
bool query(char str[]) {
int p = 0;
for (int i = 0; str[i]; i++) {
int u = str[i] - '0';
if (!tr[p][u]) return false;
p = tr[p][u];
if (cnt[p] > 0) return true;
}
return true;
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
cin >> t;
while (t--) {
idx = 0;
memset(cnt, 0, sizeof cnt);
memset(tr, 0, sizeof tr);
cin >> n;
bool flag = true;
while (n--) {
cin >> s;
if (query(s)) flag = false;
insert(s);
}
if (flag) cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}