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);//之前没释放内存超时了。。
    }
}

 

 

posted @ 2015-07-30 22:32  sweat123  阅读(219)  评论(0编辑  收藏  举报