2020“远光杯”网络资格赛S 鲍勃的输入法(字典树)

题目
鲍勃最近在写论文,为了提升写作效率他需要一款好用的输入法。然而,市面上的输入法大都是为普罗大众准备的,词库中往往没有论文里需要的专有词汇。于是鲍勃决定自己开发一款输入法,帮助自己更高效的完成论文。

输入要求
输入法首先需要构建词库。第一行是一个数字n,代表词库的词数(n ≤ 100000),随后n行内容为n个单词,需要用这些单词构建词库。单词由不超过50个小写字母构成。单词可能重复,词库中重复出现的单词输入法视为同一个单词。

下一行是一个数字q,代表接下来输入法输入q个单词(q ≤10000),随后q行内容为q个单词,代表需要输入的单词。单词由不超过50个小写字母构成。若输入单词不在词库中,且词库中没有以这个单词为前缀的其他单词,这个单词应当被加入词库中。

输出要求
当一个单词被输入后,输入法应将词库中所有以此单词为前缀的单词作为候选词输出。当前单词本身也应作为候选词输出,不论这个词是否在词库中。候选词需按照字典序输出,每个词输出完成后均有一换行。因输入法UI面积有限,每次最多输出50个候选词。

输入

5
too
young
simple
naive
coffee
5
naive
angry
co
covfefe
co

输出

naive
angry
co
coffee
covfefe
co
coffee
covfefe

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long 

struct Tree {
	Tree* nxt[26];
	bool flag;
	Tree() {
		memset(nxt,0,sizeof(nxt));
		flag = 0;
	}
}*root;
int n,q;
char s[110];
int num;
void insert1() {
	Tree *rt = root;
	int len = strlen(s);
	for(int i = 0,x;i < len;++i) {
		x = s[i]-'a';
		if(rt->nxt[x] == NULL) {
			rt->nxt[x] = new Tree();
		}
		rt = rt->nxt[x];
	}
	rt->flag = 1;
}
void dfs(int len,Tree *rt) {
	if(!num) return;
	if(rt->flag == 1) {
		s[len] = '\0';
		printf("%s\n",s);
		if(--num == 0) return;
	}
	for(int i = 0;i < 26;++i) {
		if(rt->nxt[i] != NULL) {
			s[len] = 'a'+i;
			dfs(len+1,rt->nxt[i]);
			if(!num) return;
		}
	}
}
void find1() {
	Tree *rt = root;
	int len = strlen(s);
	bool f = 1;
	for(int i = 0,x;i < len;++i) {
		x = s[i]-'a';
		if(rt->nxt[x] == NULL) {
			rt->nxt[x] = new Tree();
			f = 0;
		}
		rt = rt->nxt[x];
	}
	printf("%s\n",s);
	if(!f)
		rt->flag = 1;
	else {
		num = 49;
		for(int i = 0;i < 26;++i) {
			if(rt->nxt[i] != NULL) {
				s[len] = 'a'+i;
				dfs(len+1,rt->nxt[i]);
				if(!num) return;
			}
		}
	}
}
int main() {
	scanf("%d",&n);
	root = new Tree();
	for(int i = 0;i < n;++i) {
		scanf("%s",s);
		insert1();
	}
	scanf("%d",&q);
	while(q--) {
		scanf("%s",s);
		find1();
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值