[ 字典树题目 ]

##HDU 1251 - 统计难题

###Problem Description
Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀).

###Input
输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每个提问都是一个字符串.

注意:本题只有一组测试数据,处理到文件结束.

###Output
对于每个提问,给出以该字符串为前缀的单词的数量.

###Sample Input
banana
band
bee
absolute
acm

ba
b
band
abc

###Sample Output
2
3
1
0

思路:很裸的字典树的裸题,如果暴力的话很容易tle
大神链接私戳
用G++交题MLE了, c++才过

AC code:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

char temp[15];
int n,m;

struct trie{
	int counter;
	trie* nxt[26];
}*rt;

trie* build() {
	trie* tmp = new trie;
	tmp -> counter = 0;
	memset(tmp -> nxt , 0 ,sizeof(tmp -> nxt));
	return tmp;
}

void insert(char* s) {
	trie* r = rt;
	char* word = s;
	while(*word) {
		int id = *word - 'a';
		if ( r -> nxt[id] == NULL ) r -> nxt[id] = build();
		r = r -> nxt[id];
		r -> counter ++;
		word++;
	}
}

int search(char* s) {
	trie* r = rt;
	char* word = s;
	while(*word) {
		int id = *word - 'a';
		if ( r -> nxt[id] == NULL ) return 0;
		r = r -> nxt[id];
		*word++;
	} 
	return r -> counter;
}

int main(){
	rt = build();
	while(gets(temp)) {
		if(strlen(temp) == 0) break;
		insert(temp);
	}
	while (gets(temp)) {
		printf("%d\n",search(temp));
	}
	return 0;
}

##CODE [VS] 4189 字典

###题目描述 Description
最经,skyzhong得到了一本好厉害的字典,这个字典里整整有n个单词(1<=n<=200000)
现在skyzhong需要在字典里查询以某一段字母开头的单词
如:skyzhong想查询a
那么只要是a开头的单词就可以了
skyzhong只想知道里面有没有这一个单词(因为没有他就不查了)
若有,请输出YES。若没有,请输出NO

###输入描述 Input Description
第一行一个数n
第二行到第n+1行,一行一个字符串
再下一行一个数m,表示skyzhong想要查询的次数
接着m行,一行一个字符串,表示skyzhong想要查的东西

###输出描述 Output Description
共m行,若有这字串输出YES,否则输出NO

###样例输入 Sample Input
3
asd
asfdghj
asfd
3
asd
asdghj
asf

###样例输出 Sample Output
YES
NO
YES

###数据范围及提示 Data Size & Hint
字符串只有小写字母,且长度≤8

AC code:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

struct trie{
	trie* nxt[26];
}*rt;

char temp[15];

trie* build() {
	trie* r = new trie;
	memset(r -> nxt , 0 , sizeof(r -> nxt));
	return r;
}

void insert(char* s) {
	trie* r = rt;
	char* word = s;
	while( *word ) {
		int id = *word - 'a';
		if ( r -> nxt[id] == NULL ) r -> nxt[id] = build();
		r = r -> nxt[id];
		*word++;
	}
}

bool serach(char* s) {
	trie* r = rt;
	char* word = s;
	while( *word ) {
		int id = *word - 'a';
		if ( r -> nxt[id] == NULL ) return false;
		r = r -> nxt[id];
		*word ++;
	} 
	return true; 
}

int main(){
	rt = build();
	int n,m; scanf("%d",&n);
	for (int i = 1;i<=n;i++) {
		scanf("%s",temp); insert(temp);
	} scanf("%d",&m);
	for (int i = 1;i<=m;i++) {
		scanf("%s",temp);
		if ( serach(temp) ) printf("YES\n");
		else printf("NO\n");
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值