题目来自洛谷网站:
字典树思路:
①将数据全部存入到字典树中,同时,将字符串结尾字符的编号存入到st数组中。
②在对名字查找前,判断一下,如果名字没出现在集合中:check.count(x)==0,那么名字就不是重复的名字了。如果返回的是1的话,那么这个名字就重复了。
③在字典树中查找教练说的名字,如果没找到,直接返回false。如果找到了,返回st[p]。st[p]为true,则名字正确,为false,名字错误。
④本题注意数据范围,最多有1e4个名字,每个名字最多有50个字母。 N = 1e4*50
字典树代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 5e5;
int n, m;
//字典树trie 编号idx
int trie[N][27], idx;
//存的是编号 记录字符串是以什么字符结尾
bool st[N];
//判断是否重复
unordered_set<string> check;
//存入字典树
void add(string x){
//指针0开始
int p = 0;
for(auto i:x){
//找到i字符的映射值
int j = i - 'a';
//树中没有
if(!trie[p][j]){
trie[p][j] = ++idx;
}
//trie[p][j] 作为新的节点
p = trie[p][j];
}
st[p] = true;
}
//在字典树中查找
bool query(string x){
int p = 0;
for(auto i: x){
int j = i-'a';
if(!trie[p][j]){
return false;
}
p = trie[p][j];
}
//判断一下结尾是否存过
return st[p];
}
signed main(){
cin >> n;
for(int i = 1; i <= n; i++){
string x; cin >> x;
//存入
add(x);
}
//查找
cin >> m;
while(m--){
string x; cin >> x;
//判断有没有重复
if(!check.count(x)){
if(query(x)) cout << "OK" << endl;
else cout << "WRONG" << endl;
check.insert(x);
}
else cout << "REPEAT" << endl;
}
return 0;
}