P2580 于是他错误的点名开始了 ( 字典树

#include <bits/stdc++.h>
using namespace std;
int n, m;
int q[520000][26];
int idx;
int cnt[10100000];


void add(char str[]) {

	int p = 0;//指向地址idx的指针
	for (int i = 0 ; str[i]; i++) {
		int u = str[i] - 'a';
		if ( !q[p][u] )//判断这个地址是否存在值为u的叶节点
			q[p][u] = ++idx;//如果不存在就新建一下,给他一个地址
		p = q[p][u];//将p移动下一个节点的地址
	}

	cnt[p] = 1;

}

int query(char str[]) {
	int p = 0;
	for (int i = 0; str[i]; i++) {
		int u = str[i] - 'a';
		if ( !q[p][u] )//判断叶节点是否存在
			return 0;
		p = q[p][u];
	}

	if (cnt[p] == 1)// 如果这个地址下表的标记为1,就表示点对了,++一下下次别点了
		return cnt[p]++;
	else if(cnt[p] == 0)//如果到了这个下表但是并没有这个人,上面的那个退出只能是这个字符串不存在,但也可能存在字符串存在,人不存在的可能
		return 0;       
	else 
		return -1;//重复点了返回 -1 

}

int main() {
	cin >> n;
	while (n--) {
		char str[51];
		cin >> str;
		add(str);
	}
	cin >> m;
	while (m--) {
		char str[51];
		cin >> str;
		int flag = query(str);
		if (flag == 1)
			cout << "OK";
		else if (flag == 0)
			cout << "WRONG";
		else
			cout << "REPEAT";

		cout << endl;

	}
}


查询循环中的推出是判断字符串能否存在,循环后得分别判断三件事,字符串是否为1,这个字符串虽然存在但是不是名字,是否重复。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值