字典树
这里的trie[][]存的是数字字符,若需要存储任意字符可将第二维设置[128].
一维的长度要自己判断,最差情况就是每个字符串的长度 * 字符串的个数= len * n。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 10;
int trie[maxn][10]; // trie[i][j]表示第i个字符下一层的j字符为树中第几个字符
int wordcnt[maxn] = {0}; // 表示树中第i个字符为结尾的字符串数量
int cnt = 0; // 结点数量
bool f = false;
void insertStr(string s) {
int root = 0;
for (int i = 0; i < s.length(); i++) {
int x = s[i] - '0';
if (!trie[root][x]) // 当root字符的x子树不存在时才能为其分配结点号
trie[root][x] = ++cnt; // 为root结点插入x字符结点号为cnt
root = trie[root][x]; // 遍历子节点 相当于root = root->child
if (wordcnt[root]) // 长字符串发现当前字符为结尾是字符串
f = true;
}
for (int i = 0; i < 10; i++)
if (trie[root][i]) // 如果短字符串末尾发现还链接其他字符则表示是其他字符串的前缀
f = true;
wordcnt[root]++; // 用该字符串末尾字符表示以该字符串为字符串为前缀的数量
}
int main(int argc, char** argv) {
int n;
string s;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> s;
insertStr(s);
}
if (f)
printf("YES");
else
printf("NO");
return 0;
}

9402

被折叠的 条评论
为什么被折叠?



