于是他错误的点名开始了
题目链接:luogu P2580
题目大意
有一堆字符串,然后有一些询问,每次给你一个字符串,如果那一堆字符串里面没有这个字符串,就输出 WRONG,如果问的不是第一次,就输出 REPEAT,否则输出 OK。
思路
这道题主要就是 Trie 树的模板题。
主要就是一个点会有一些儿子,代表它接下来的下一个字符是哪个。
当然,这个点自己也会代表一个字符。(深度就代表它是在第几位的)
一个从根节点到一个点形成的链的每个点代表的信息组合起来,就形成了一个字符串。
那我们在这个字符串的最后一个点可以记录它的出现,以及出现的次数,以及题目要求的东西。
代码
#include<cstdio>
#include<cstring>
using namespace std;
struct Trie {
int son[26], end, point;
}trie[1000001];
int n, m, cn, now, KK, re, op;
char c[100001];
void build() {
now = 0;
for (int i = 0; i < cn; i++) {
if (!trie[now].son[c[i] - 'a']) {
trie[now].son[c[i] - 'a'] = ++KK;
}
now = trie[now].son[c[i] - 'a'];
}
trie[now].end++;//记录是否有这个字符串
}
int find() {
now = 0;
re = 0;
for (int i = 0; i < cn; i++) {
if (!trie[now].son[c[i] - 'a']) return 0;//已经确定没有这个字符串,直接是 WRONG
now = trie[now].son[c[i] - 'a'];
}
trie[now].point++;//记录询问的次数
return now;
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%s", c);
cn = strlen(c);
build();
}
scanf("%d", &m);
for (int i = 1; i <= m; i++) {
scanf("%s", c);
cn = strlen(c);
op = find();
if (!trie[op].end) printf("WRONG\n");
else if (trie[op].point > 1) printf("REPEAT\n");
else printf("OK\n");
}
return 0;
}