hdu2846 字典树
给你一堆字符串,然后再给你几个查询,前面那些字符串中有多少个包含了这个串。所以可以把开始inset()的字符遍历一遍,同时可能出现该字符串在某个字符串中有多次出现,所以还要用flag标记,来区分不同的串。
#include<stdio.h> #include<string.h> #include<stdlib.h> struct trie { int flag; int sum; trie *next[26]; }; trie *root; void init() { int i; root=(trie*)malloc(sizeof(trie)); for(i=0;i<26;i++) root->next[i]=NULL; root->sum=0; root->flag=-1; } void insert(char *s,int flag) { trie *q,*p=root; int i,j,len=strlen(s); for(i=0;i<len;i++) { int id=s[i]-'a'; if(p->next[id]==NULL) { q=(trie*)malloc(sizeof(trie)); for(j=0;j<26;j++) q->next[j]=NULL; q->sum=0; q->flag=-1; p->next[id]=q; } p=p->next[id]; if(p->flag!=flag) { p->flag=flag; p->sum++; } } } int search(char *s) { int i,j,len=strlen(s); trie *p=root; for(i=0;i<len;i++) { int id=s[i]-'a'; if(p->next[id]==NULL) { return 0; } p=p->next[id]; } return p->sum; } void freetrie(trie *root) { for(int i=0;i<26;i++) { if(root->next[i]) freetrie(root->next[i]); } free(root); } int main() { char s[22]; int i,j,n,q,flag; while(scanf("%d",&n)!=EOF) { init(); for(i=0;i<n;i++) { scanf("%s",s); int len=strlen(s); for(j=0;j<len;j++) { insert(s+j,i); } } scanf("%d",&q); while(q--) { scanf("%s",s); int ans=search(s); printf("%d\n",ans); } freetrie(root); } }