HDU1247 Hat’s Words Tire树

题目大意:给你若干字符串,让你找出这些字符串中由其他两个字符串连接成的字符串。


分析:我们很容易想到的是先把这些字符串存放到tire树中,然后分别查询每两个字符串连接构成的新字符串是否在树中,想法很美好,但这样的时间复杂度是0(n^2)的,而n是50000的,果断TLE了。后来我换了一种思路,和合并操作等价的操作就是拆分:我们遍历这n个字符串,把每个字符串可拆分的字符串找出来,分别判断他们是否在tire树中即可,这样复杂度就变为了O(n*len)其中len为字符串的最大长度,这个长度很小的(按AC的代码来看,15就足矣)。


实现代码如下:

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cstring>
using namespace std;
#define son_num 30 //字符串中包含的字符个数
#define maxn 15 //单词的最大长度
struct tire
{
    int num; //纪录到达该节点的字符串的个数,即相同前缀数
    bool terminal; //如果terminal=true,表示当前点为该字符串最后一个字符
    struct tire *next[son_num]; //纪录下一个节点
};
tire *root;
char dic[50005][maxn];

tire *init() //创建新节点
{
    tire *p=(tire *)malloc(sizeof(tire));
    for(int i=0;i<son_num;i++)
      p->next[i]=NULL;
    p->terminal=false;
    p->num=0;
    return p;
}
void insert(tire *root,char str[]) //插入操作
{
    int i=0;
    tire *p=root;
    while(str[i]!='\0')
    {
        if(!p->next[ str[i]-'a' ]) //如果不存在,建立新节点
          p->next[ str[i]-'a' ]=init();
        p=p->next[ str[i]-'a' ];
        p->num++;
        i++;
    }
    p->terminal=true;
}
bool find(tire *p,char str[]) //查找操作
{
    int i=0;
    while(str[i]!='\0'&&p->next[ str[i]-'a' ])
    {
        p=p->next[ str[i]-'a' ];
        i++;
    }
    if(str[i]=='\0'&&p->terminal) return true;  //查找字符串本身
    return false;
}
void del(tire *root) //清空操作
{
    for(int i=0;i<son_num;i++)
      if(root->next[i]!=NULL)
        del(root->next[i]);
    free(root);
}
int main()
{
    root=init();  //创建根结点
    int cnt=0;
    while(~scanf("%s",dic[cnt])) //建立字典树
    {
        insert(root,dic[cnt]);
        cnt++;
    }
    for(int i=0;i<cnt;i++) //拆分字符串并查找
    {
        int len=strlen(dic[i]);
        char tmp1[maxn],tmp2[maxn];
        for(int j=1;j<len;j++)
        {
            strncpy(tmp1,dic[i],j);
            tmp1[j]='\0';
            strncpy(tmp2,dic[i]+j,len-j);
            tmp2[len-j]='\0';
            if(find(root,tmp1)&&find(root,tmp2))
            {
                printf("%s\n",dic[i]);
                break;
            }
        }
    }
    del(root); //释放字典树占用的空间
    return 0;
}


你可能感兴趣的:(HDU1247 Hat’s Words Tire树)