题目描述
这之后校长任命你为特派探员,每天记录他的点名。校长会提供化学竞赛学生的人数和名单,而你需要告诉校长他有没有点错名。(为什么不直接不让他玩炉石。)
输入格式
第一行一个整数 n,表示班上人数。接下来 n 行,每行一个字符串表示其名字(互不相同,且只含小写字母,长度不超过 50)。第 n+2 行一个整数 m,表示教练报的名字。接下来 m 行,每行一个字符串表示教练报的名字(只含小写字母,且长度不超过 50)。
输出格式
对于每个教练报的名字,输出一行。如果该名字正确且是第一次出现,输出“OK”,如果该名字错误,输出“WRONG”,如果该名字正确但不是第一次出现,输出“REPEAT”。(均不加引号)
输入样例:
5
a
b
c
ad
acd
3
a
a
e
输出样例:
OK
REPEAT
WRONG
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
static int tot = 0;//类似内存的东西,表示trie的大小
static Node node[]; //字典树
//对于java来说大量的IO会加大开销,所以将结果存起来,最后在一起输出
static StringBuffer sb = new StringBuffer();
static class Node {
int next[] = new int[26]; //保存该节点的26个字母
boolean isDanci, isVisit; // isDanci是否单词结尾,isVisit如果是单词,是否被访问过
}
static void insert(char c[]) {
int p = 0; //从根节点出发
//遍历
for (int i = 0; i < c.length; i++) {
//查看当前节点的c[i]-'a'是否存在
int next = node[p].next[c[i] - 'a'];
//为0则表示不存在,需要生成
if (next == 0) {
//生成该节点
next = node[p].next[c[i] - 'a'] = ++tot;
node[tot] = new Node();
}
//修改当前节点
p = next;
}
//在结尾位置加上单词标记
node[p].isDanci = true;
}
static void query(char c[]) {
int p = 0;
for (int i = 0; i < c.length; i++) {
int next = node[p].next[c[i] - 'a'];
//如果该位置不存在,则证明单词不在树中
if (next == 0) {
sb.append("WRONG" + "\n");
return;
}
p = next;
}
//到了结尾,但是该位置没有单词标记,也证明单词不在树中
if (!node[p].isDanci) {
sb.append("WRONG" + "\n");
return;
}
//如果访问过
if (node[p].isVisit) {
sb.append("REPEAT" + "\n");
return;
}
sb.append("OK" + "\n");
//设置访问过的标记
node[p].isVisit = true;
}
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(reader.readLine().trim());
//大小要根据题目所定,题目表示每个单词不超过50,所以考虑最坏的情况,50*n+1,+1是给根节点
node = new Node[n * 50 + 1];
//初始化根节点
node[0] = new Node();
//初始化字典树
for (int i = 0; i < n; i++)
insert(reader.readLine().trim().toCharArray());
int m = Integer.parseInt(reader.readLine().trim());
//查找字典树
for (int i = 0; i < m; i++)
query(reader.readLine().trim().toCharArray());
//输出结果
System.out.println(sb);
}
}