Repository
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2633 Accepted Submission(s): 1028
Problem Description
When you go shopping, you can search in repository for avalible merchandises by the computers and internet. First you give the search system a name about something, then the system responds with the results. Now you are given a lot
merchandise names in repository and some queries, and required to simulate the process.
Input
There is only one case. First there is an integer P (1<=P<=10000)representing the number of the merchanidse names in the repository. The next P lines each contain a string (it‘s length isn‘t beyond 20,and all the letters are lowercase).Then
there is an integer Q(1<=Q<=100000) representing the number of the queries. The next Q lines each contains a string(the same limitation as foregoing descriptions) as the searching condition.
Output
For each query, you just output the number of the merchandises, whose names contain the search string as their substrings.
Sample Input
20 ad ae af ag ah ai aj ak al ads add ade adf adg adh adi adj adk adl aes 5 b a d ad s
Sample Output
0 20 11 11 2
我的AC状态,,我总感觉自己好笨的。。脑子不太灵活,第一次写的时候超时了,,来说一下思路吧,,就是把一个字符串abcde,分别拆成abcde,bcde,cde,de,e,存到字典树里,因为会出现会abcab这样的字符串,他的字串有俩个ab开头的,,所以得在结构体里加上一个id标签,,把id设为最后一个存到字典树里的字符串。看代码就知道啦,很容易懂的
下面是AC代码:
#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX 20000 struct Trie{ int count; //储存相同字符串的数目 int id ; //标识已储存过的字符串,防止重复计算。 Trie *next[26]; }; //建树 void build(Trie *t , char name[] , int id) { int len =strlen(name) ; for(int i = 0 ; i < len; ++i) { if(t->next[name[i]-'a'] == NULL) { Trie *temp = (Trie*)malloc(sizeof(Trie)) ; temp->count=1; temp->id = id ; for(int j = 0 ; j < 26 ; ++j) { temp->next[j] = NULL ; } t->next[name[i]-'a'] = temp ; t = temp ; } else { t = t->next[name[i]-'a'] ; if(id != t->id) t->count ++; t->id = id ; } } } int count = 0 ; bool flag[MAX] ; //查询 void query(Trie *t , char str[]) { int len = strlen(str) , i ; for(i = 0 ; i < len ; ++i) { if(t->next[str[i]-'a'] != NULL) { t = t->next[str[i]-'a'] ; } else { break ; } } if( i == len ) { if(!flag[t->id]) { count += t->count ; flag[t->id] = true ; } } } int main() { int n ; scanf("%d",&n); Trie *t=(Trie *)malloc(sizeof(Trie)); for(int i = 0 ; i < 26 ; ++i) { t->next[i] = NULL ; } t->count = 0 ; for(int i =0 ; i < n ; ++i) { char name[30]; scanf("%s",name) ; int len = strlen(name) ; for(int j = 0 ; j < len ; ++j) { build(t,name+j,i); } } int q; scanf("%d",&q); for(int i = 0 ; i < q ; ++i) { memset(flag,0,sizeof(flag)) ; char str[30]; count = 0 ; scanf("%s",str); query(t,str) ; printf("%d\n",count) ; } return 0 ; }
//严格的来说,如果是测试多组测试数据,,应该释放内存,,但是就一组测试数据,释不释放都无所谓啦!下面超时的代码里有释放内存的函数,如果想知道怎么释放,可以参考下面的代码。
下面是第一次超时的代码,,大家可以无视跳过。。
#include <stdio.h> #include <stdlib.h> #include <string.h> struct Trie{ int count; Trie *next[26]; }; void build(Trie *t , char name[]) { int len =strlen(name) ; for(int i = 0 ; i < len; ++i) { if(t->next[name[i]-'a'] == NULL) { Trie *temp = (Trie *)malloc(sizeof(Trie)) ; temp->count=1; for(int j = 0 ; j < 26 ; ++j) { temp->next[j] = NULL ; } t->next[name[i]-'a'] = temp ; t = temp ; } else { t = t->next[name[i]-'a'] ; t->count ++; } } } int count = 0 ; void query(Trie *t , char str[],int index) { if(index == strlen(str)) { count += t->count ; return ; } for(int i = 0 ; i < 26 ; ++i) { if(t->next[i] != NULL) { if(i == str[index]-'a') { query(t->next[i],str,index+1); } else { query(t->next[i],str,0) ; } } } } void destroy(Trie *t) { for(int i = 0 ; i < 26 ; ++i) { if(t->next[i] != NULL) destroy(t->next[i]) ; } free(t); } int main() { int n ; scanf("%d",&n); Trie *t=(Trie *)malloc(sizeof(Trie)); for(int i = 0 ; i < 26 ; ++i) { t->next[i] = NULL ; } t->count = 0 ; for(int i =0 ; i < n ; ++i) { char name[30]; scanf("%s",name) ; build(t,name); } int q; scanf("%d",&q); for(int i = 0 ; i < q ; ++i) { char str[30]; count = 0 ; scanf("%s",str); query(t,str,0) ; printf("%d\n",count) ; } destroy(t) ; return 0 ; }
可能这个代码没什么用,就作为给自己的一个警告吧!
下面是正确的代码