[HDOJ1251]统计偏题
[HDOJ1251]统计难题
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1251
统计难题
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131070/65535 K (Java/Others)
Total Submission(s): 25281 Accepted Submission(s): 10366
Problem Description
Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀).
Input
输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每个提问都是一个字符串.
注意:本题只有一组测试数据,处理到文件结束.
注意:本题只有一组测试数据,处理到文件结束.
Output
对于每个提问,给出以该字符串为前缀的单词的数量.
Sample Input
banana
band
bee
absolute
acm
ba
b
band
abc
Sample Output
2
3
1
0
字典树,这个写得不好,因为new的时候很耗费内存。用G++编译的时候还爆MLE了。C++过的。具体做法就是直接在向字典树插入字符的时候在对应位置的节点加1,表示当前节点又被走过了1次。查找的时候输出对应字串末位字符的cnt值就可以了。注意处理没有该词的情况。
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <algorithm> 5 #include <iostream> 6 #include <cmath> 7 #include <queue> 8 #include <map> 9 #include <stack> 10 #include <list> 11 #include <vector> 12 13 using namespace std; 14 15 char str[11]; 16 typedef struct Node { 17 Node *next[26]; 18 int cnt; 19 Node() { 20 cnt = 0; 21 for(int i = 0; i < 26; i++) { 22 next[i] = NULL; 23 } 24 } 25 }Node; 26 27 void insert(Node *p, char *str) { 28 for(int i = 0; str[i]; i++) { 29 int t = str[i] - 'a'; 30 if(p->next[t] == NULL) { 31 p->next[t] = new Node; 32 } 33 p = p->next[t]; 34 p->cnt++; 35 } 36 } 37 38 int find(Node *p, char *str) { 39 for(int i = 0; str[i]; i++) { 40 int t = str[i] - 'a'; 41 p = p->next[t]; 42 if(!p) { 43 return 0; 44 } 45 } 46 return p->cnt; 47 } 48 49 int main() { 50 Node *root = new Node(); 51 while(gets(str) && strlen(str)) { 52 insert(root, str); 53 } 54 while(gets(str)) { 55 int ans = find(root, str); 56 printf("%d\n", ans); 57 } 58 return 0; 59 }