于是他錯誤的點名開始了
題目連結: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;
}