------明天开始作线段树和树状数组啦,字典树先告一段落
《Hat’s Words》就是纯粹的字典树模板啊。。插入完了查找。。只是查找的时候要把每个单词拆分成所有左右两部分的组合来查找。
题意:按字典序给出若干个单词,查找这些单词里面是否有这样的单词,就是某个单词是由另外两个单词拼接而成的。如果有输出这个单词,把满足条件的这样的单词也按字典序输出。。
思路:把每个单词都存入字典树,然后再拆分每个单词,如果拆分后的两部分在字典树中都能查找到,就输出,因为输入是按字典序输入的。所以输出时也按顺序判断就好了。
字典树的意思就是先给一个根节点,然后顺着这条根节点往下连接儿子节点的那条边作为单词的一个字母,如果存在这个字母就下去找那个儿子节点,然后同理找下一个字母。不存在这个字母的话,根节点就再生一个儿子,然后继续不断地生..查找同理,字母不存在就说明没这个单词
本题代码
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <iostream>
#include <algorithm>
#include <map>
using namespace std;
char a[100];
char b[50010][100];
char c[100];
int ch[50010][26];
int val[50010], tmp;
void insert(char *a)
{
int rt = 0, x;
for (int i = 0; a[i]; i++)
{
x = a[i] - 'a';
if (ch[rt][x] == 0)
{
val[tmp] = 0;
ch[rt][x] = tmp++;
}
rt = ch[rt][x];
}
val[rt] = 1;
}
int find(char *b)
{
int rt = 0, x;
for (int i = 0; b[i]; i++)
{
x = b[i] - 'a';
if (ch[rt][x] == 0)
{
return 0;
}
rt = ch[rt][x];
}
if (val[rt] == 1) return 1;
else return 0;
}
int main()
{
int top = 0;
tmp = 1;
val[0] = 0;
memset(ch[0], 0, sizeof ch);
while (scanf("%s", a) == 1)
{
insert(a);
strcpy(b[top++], a);
}
int i, j, len;
for (i = 0; i < top; i++)
{
len = strlen(b[i]);
for (j = 1; j < len; j++)
{
strcpy(c, b[i]);
c[j] = '\0';
if (find(c) && find(b[i]+j))
{
printf("%s\n", b[i]);
break;
}
}
}
return 0;
}