Description
Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀).
Input
输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每个提问都是一个字符串.
注意:本题只有一组测试数据,处理到文件结束.
注意:本题只有一组测试数据,处理到文件结束.
Output
对于每个提问,给出以该字符串为前缀的单词的数量.
Sample Input
banana band bee absolute acm ba b band abc
Sample Output
2 3 1 0第二次做这题了,好久没接触trie树,好多知识都忘了。一开始感觉是直接最长的字母长度为深度,一直向下写就行了。但是一直没结果,原来是我没理解。因为如果是动态的话,他是26叉树,所以肯定有很多节点,要开很大的空间才行。静态版:#include<iostream> #include<algorithm> #include<cstdlib> #include<cstring> #include<string> #include<cstdio> #include<vector> #include<cmath> #include<map> using namespace std; #define T 500005 #define inf 0x3f3f3f3f #define CRL(a) memset(a,0,sizeof(a)) typedef long long ll; struct trie { int v; int kid[26]; trie() { v=0;CRL(kid); } }tr[T]; char s[T]; int c=1; void insert() { int i,x=0,d; for(i=0;s[i];++i){ d = s[i]-'a'; if(tr[x].kid[d]==0){ tr[x].kid[d]=c++; x=c-1; } else x = tr[x].kid[d]; tr[x].v++; } } int find() { int i,x=0,d; for(i=0;s[i];++i){ d = s[i]-'a'; if(tr[x].kid[d]==0) return 0; x = tr[x].kid[d]; } return tr[x].v; } int main() { /*freopen("input.txt","r",stdin);*/ while(cin.getline(s,T)&&s[0]!='\0') { insert(); } while(cin.getline(s,T)) { printf("%d\n",find()); } return 0; }
这题非常的水但是就是整天内存超限。让我非常不爽的是根本就是编译器的问题,用G++提交肯定超限,用c++就不超了,还有就是感谢杭电里面的讨论,让我知道为什么总是优化不出来,原来是系统问题。AC代码:#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> using namespace std; struct S { int value; S* kid[26]; S() { value=0; for(int i=0;i<26;++i) { kid[i]=NULL; } } }*root; void insert(char* str) { S* t=root; int d; for(int i=0;str[i];++i) { d=str[i]-'a'; if(t->kid[d]==NULL) { t->kid[d] = new S; } t=t->kid[d]; t->value++; } } int find(char* str) { S* t = root; int d; for(int i=0;str[i];++i) { d = str[i]-'a'; if(t->kid[d]==NULL) { return 0; } t = t->kid[d]; } return t->value; } int main() { char str[15]; root = new S; while(gets(str)&&str[0]) { insert(str); } while(~scanf("%s",&str)) { printf("%d\n",find(str)); } return 0; }