HDU 1247 Hat’s Words(字典树Trie)
http://acm.hdu.edu.cn/showproblem.php?pid=1247
题意:
给你多个单词组成的字典,要你从中找出这样的单词,该单词正好是字典中另外两个单词(可相同)首尾相连构成的。按字典序输出所有要找的单词。
分析:
首先用所有单词建立字典树,然后遍历每个单词。将当前单词分成两段(枚举所有划分单词的方法)看看这两段单词是不是都已经在Trie里面了。
注意:由于输入单词是按照字典序输入的,所以我们不用去排序所有单词了。
源代码实现的比较暴力,其实可以用当前考察的单词去匹配字典树,如果匹配了一个字典树的单词,就将被考察单词的剩余部分继续从新匹配字典树看看是否正好也匹配一个单词。
AC代码#include <iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int maxnode=1000000+100;
const int sigma_size=26;
struct Trie
{
int ch[maxnode][sigma_size];
int val[maxnode];
int sz;
void init()
{
sz=1;
memset(ch[0],0,sizeof(ch[0]));
val[0]=0;
}
void insert(char *s)
{
int n=strlen(s),u=0;
for(int i=0;i<n;i++)
{
int id=s[i]-'a';
if(ch[u][id]==0)
{
val[sz]=0;
ch[u][id]=sz;
memset(ch[sz],0,sizeof(ch[sz]));
sz++;
}
u=ch[u][id];
}
val[u]=1;
}
bool search(char *s)
{
int n=strlen(s),u=0;
for(int i=0;i<n;i++)
{
int id=s[i]-'a';
if(ch[u][id]==0)
return false;
u=ch[u][id];
}
return val[u];
}
};
Trie trie;
char word[50000+100][50];
int main()
{
trie.init();
int cnt=0;
while(gets(word[cnt]))
{
trie.insert(word[cnt++]);
}
for(int k=0;k<cnt;k++)
{
int len=strlen(word[k]);
for(int i=1;i<len;i++)
{
char str1[50],str2[50];
strncpy(str1,word[k],i);
str1[i]=0;
strncpy(str2,word[k]+i,len-i);
str2[len-i]=0;
if(trie.search(str1) && trie.search(str2))
{
printf("%s\n",word[k]);
break;
}
}
}
return 0;
}