【luogu P2580】【Trie树】于是他错误的点名开始了

于是他错误的点名开始了

题目链接: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;
}

猜你喜欢

转载自blog.csdn.net/weixin_43346722/article/details/112991030