【Trie】【HDU1247】【Hat’s Wordsfd2】

时间:2022-05-22 18:02:38

题目大意:

hat's word 的定义是字典中 恰好由另外两个单词连接起来的单词

给你一本字典,问有多少个hat‘s word,(字典按字典序给出)

单词数50000..

初步思路:

单词分为前缀单词,后缀单词

前缀单词出现在字典的前面,后缀单词出现在字典后面?

1.枚举前缀,哈希判断后缀?

复杂度:N^N*单词平均长度,显然不靠谱

2.trie树?

先建树,然后对于每一个单词读入,如果经过了某些单词结尾,判断一下后缀有没有.

复杂度似乎可靠?写写吧....

代码写成功..样例过..RE..字典树过大?.,..RE无数发 发现

int find_trie(char *s)
{
trie *root=TREE;
for(int i=0;s[i];i++)
{
int t=s[i]-'a';
if(root->next[t]==NULL) return 0;//写成root->next==NULL root=root->next[t];
}
if(root->flag==1) return 1;
else return 0;
}
</pre><p></p><p><span style="font-size:24px">已A.</span></p><p><span style="font-size:24px"></span></p><pre code_snippet_id="658096" snippet_file_name="blog_20150503_3_3616348" name="code" class="cpp">#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#define oo 0x13131313
using namespace std;
char buffer[50005][205];
struct trie{
trie *next[30];
int flag;
}TREE[200000],*EE;
void insert_trie(char *s)
{
trie *root=TREE;
for(int i=0;s[i];i++)
{
int t=s[i]-'a';
if(root->next[t]==NULL) { root->next[t]=EE++;}
root=root->next[t];
}
root->flag=1;
}
int find_trie(char *s)
{
trie *root=TREE;
for(int i=0;s[i];i++)
{
int t=s[i]-'a';
if(root->next[t]==NULL) return 0;
root=root->next[t];
}
if(root->flag==1) return 1;
else return 0;
}
void solve_trie(char *s)
{
int ok=0;
trie *root=TREE;
for(int i=0;s[i];i++)
{
int t=s[i]-'a';
root=root->next[t];
if(root->flag==1)
if(find_trie(s+i+1)==1)
{
ok=1;
break;
}
}
if(ok) printf("%s\n",s);
}
void Clear()
{
memset(TREE,0,sizeof(TREE));
EE=TREE+1;
}
void init()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
}
int main()
{
int p=0;
// init();
Clear();
while(scanf("%s",buffer[++p])!=EOF)
insert_trie(buffer[p]);
for(int i=1;i<=p;i++)
{
solve_trie(buffer[i]);
}
return 0;
}