HDU 1247 Hat’s Words(字典树)

 

题目大意

 

字典中,一个单词是一个 hat's word:这个单词可以由字典中另外两个单词拼接而成

给你一个字典,求出字典中所有的 hat's word

单词最多有 50000 个

 

做法分析

 

看到这道题,感觉无从下手,单词的数量这么多,但是仔细一想,单词数是多了,但是如果每个单词的平均长度必然就小了,不然光是读入数据就得超时

于是,先乱搞一发再说

 

建立一棵字典树,然后,对于每个单词,直接暴力,竟然神奇的过了!

暴力的做法是:枚举第一个子单词的长度,剩下的为第二个子单词,分别在字典树中匹配,看能否找到一个单词与两个单词匹配,能的话,这是一个 hat's word

 

参考代码

 

HDU 1247
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 
 6 using namespace std;
 7 
 8 struct Tire
 9 {
10     struct Node
11     {
12         Node *next[26];
13         bool flag;
14         Node()
15         {
16             for(int i=0; i<26; i++) next[i]=NULL;
17             flag=0;
18         }
19     };
20     Node *root;
21     Tire()
22     {
23         root=new Node();
24     }
25 
26     void Insert(char s[])
27     {
28         Node *u=root;
29         for(int i=0; s[i]; i++)
30         {
31             int v=s[i]-'a';
32             if(u->next[v]==NULL) u->next[v]=new Node();
33             u=u->next[v];
34         }
35         u->flag=1;
36     }
37 
38     bool Find(char buff[], int s, int t)
39     {
40         Node *u=root;
41         for(int i=s; i<=t; i++)
42         {
43             int v=buff[i]-'a';
44             if(u->next[v]==NULL) return false;
45             u=u->next[v];
46         }
47         return u->flag;
48     }
49 } tree;
50 
51 char s[50005][100];
52 int tot;
53 
54 int main()
55 {
56     for(tot=0; scanf("%s", s[tot])!=EOF; tot++)
57         tree.Insert(s[tot]);
58     for(int i=0; i<tot; i++)
59     {
60         int t=(int)strlen(s[i])-1;
61         for(int j=0; j<t; j++)
62             if(tree.Find(s[i], 0, j) && tree.Find(s[i], j+1, t))
63             {
64                 printf("%s\n", s[i]);
65                 break;
66             }
67     }
68     return 0;
69 }

AC通道

HDU 1247 Hat’s Words

原文地址:https://www.cnblogs.com/zhj5chengfeng/p/3021584.html