【HDU 1247 Hat’s Words】字典树(Trie树)

HDU1247
本题题意是问你某个单词是否可以拆成单词表中的其他两个单词。
我们可以建两颗Trie树,然后分别正序倒序插入每个单词,对每个单词查询的时候,我们分别正序倒序查询,对出现过单词的前缀下表进行标记,对每个出现过单词的后缀进行标记,最后扫描标记数组,如果某个位置前缀后缀均被标记过,则表示可以拆成单词表中的两个其他单词。
HDU1247代码

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<sstream>
#include<set>
using namespace std;
const int maxn =2e6+5;
int tree[maxn][30],tree2[maxn][30];
set<string> s;
bool flagg[maxn],flagg2[maxn];
int sum[55];
int tot,tot2;
void insert_(char *str)
{
   int len=strlen(str);
   int root=0;
   for(int i=0;i<len;i++)
   {
       int id=str[i]-'a';
       if(!tree[root][id]) tree[root][id]=++tot;
       root=tree[root][id];
   }
   flagg[root]=true;
   return ;
}
void find_(char *str)
{
    int len=strlen(str);
    int root=0;
    for(int i=0;i<len-1;i++)
    {
        int id=str[i]-'a';
        root=tree[root][id];
        if(flagg[root]) sum[i]++;//当前前缀是其他单词
    }
    return ;
}
void insert2_(char *str)
{
   int len=strlen(str);
   int root=0;
   for(int i=0;i<len;i++)
   {
       int id=str[i]-'a';
       if(!tree2[root][id]) tree2[root][id]=++tot2;
       root=tree2[root][id];
   }
   flagg2[root]=true;
   return ;
}
void  find2_(char *str)
{
    int len=strlen(str);
    int root=0;
    for(int i=0;i<len-1;i++)
    {
        int id=str[i]-'a';
        root=tree2[root][id];
        if(flagg2[root])
        {
            sum[len-i-2]++;//当前前缀是其他单词,对反转后的位置进行标记
        }
    }
    return ;
}
char ss[50005][55];
int main()
{
    int cnt=0;
    while(scanf("%s",ss[cnt++])!=EOF)
    {
        insert_(ss[cnt-1]);//正序插入到第一棵树
        strrev(ss[cnt-1]);
        insert2_(ss[cnt-1]);//倒叙插入第二颗树
        strrev(ss[cnt-1]);
    }
    for(int i=0;i<cnt;i++)
    {
        int len=strlen(ss[i]);
        for(int j=0;j<len;j++)
        {
            sum[j]=0;
        }
        find_(ss[i]);//在第一棵树上查询并标记
        strrev(ss[i]);
        find2_(ss[i]);//在第二颗树上查询并标记
        strrev(ss[i]);
        for(int j=0;j<len;j++)
        {
            if(sum[j]==2)//两次查询均标记过的位置
            {
                string tmp=ss[i];
                s.insert(tmp);
                break;
            }
        }
    }
    set<string>::iterator it;
    for(it=s.begin();it!=s.end();++it)
    {
        printf("%s\n",(*it).c_str());
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_38891827/article/details/80673031