hdu2222 字典树
要注意二点 。
这组数据
1 6 she he he say shr her yasherhs
出现重复的,也要算。所以这里答案为4;
这一组
1 6 she he he say shr her yasherhe
查询单词中he出现过,所以后面的he不能记录,所以答案为4;
#include<stdio.h> #include<string.h> #include<stdlib.h> struct trie { trie *next[26]; int flag; int ok; }; trie *root; void init() { root=(trie*)malloc(sizeof(trie)); for(int i=0;i<26;i++) root->next[i]=NULL; root->flag=0;//标记是否有单词 root->ok=0;//标记该单词是否已经被使用 } void insert(char *str) { int i,j,len=strlen(str); trie *p=root,*q; for(i=0;i<len;i++) { int id=str[i]-'a'; if(p->next[id]==NULL) { q=(trie*)malloc(sizeof(trie)); for(j=0;j<26;j++) q->next[j]=NULL; q->flag=0; q->ok=0; p->next[id]=q; } p=p->next[id]; if(i==len-1) p->flag++; } } int query(char *str) { int i,j,len=strlen(str); int ans=0,flag; for(i=0;i<len;i++) { trie *p=root; flag=0; for(j=i;j<len;j++) { int id=str[j]-'a'; if(p->next[id]==NULL) { flag=1; break; } p=p->next[id]; if(p->flag>0&&!p->ok)//flag标记是否有单词,ok标记该单词是否被使用 { p->ok=1; ans+=p->flag; } } if(!flag) i+=j-i; } return ans; } void freetrie(trie *p) { for(int i=0;i<26;i++) { if(p->next[i]!=NULL) freetrie(p->next[i]); } free(p); } char temp[1000002]; int main() { int i,j,n,t;; scanf("%d",&t); while(t--) { init(); char str[52]; scanf("%d",&n); for(i=0;i<n;i++) { scanf("%s",str); insert(str); } scanf("%s",temp); int ans=query(temp); printf("%d\n",ans); freetrie(root);//之前没释放内存超时了。。 } }