hdu1247 字典树

开始以为枚举会超时,因为有50000的词。后来试了一发就过了。哈哈。枚举没一个单词,将单词拆为2半,如果2半都出现过,那就是要求的。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct trie
{
    trie *next[26];
    int flag;
};
trie *root;
void init()
{
    int i;
    root=(trie*)malloc(sizeof(trie));
    for(i=0;i<26;i++)
        root->next[i]=NULL;
    root->flag=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;
            p->next[id]=q;
        }
        p=p->next[id];
        if(i==len-1)
        {
            p->flag=1;
        }
    }
}
int query(char *str)
{
    int i,j,len=strlen(str);
    trie *p=root;
    for(i=0;i<len;i++)
    {
        int id=str[i]-'a';
        if(p->next[id]==NULL)
            return 0;
        p=p->next[id];
    }
    if(p->flag>0)
        return 1;
    return 0;
}
char str[50001][30];
int main()
{
    int i,j,count=0;
    int flag;
    init();
    while(gets(str[count]))
    {
        if(strcmp(str[count],"")==0)break;
        insert(str[count]);
        count++;
    }
    for(i=0;i<count;i++)
    {
        if(strlen(str[i])==1)continue;
        char s1[16],s2[16];
        int l1,l2,k;
        int l=strlen(str[i]);
        for(j=1;j<l;j++)//枚举单词,将单词一分为二,查询是否都出现。如果是这个单词就ok了。
        {
            flag=0;
            l1=l2=0;
            for(k=0;k<j;k++)//左子串
            {
                s1[l1]=str[i][k];
                l1++;
            }
            s1[l1]='\0';
            for(k=j;k<l;k++)//右边子串
            {
                s2[l2]=str[i][k];
                l2++;
            }
            s2[l2]='\0';
            if(query(s1)&&query(s2))//查询
            {
                flag=1;
                break;
            }
        }
        if(flag)
            printf("%s\n",str[i]);
    }
    return 0;
}

 

posted @ 2015-07-30 15:38  sweat123  阅读(126)  评论(0编辑  收藏  举报