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
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 ; }