Hat’s Words
题意:
如果一个单词可以由其他两个单词拼接而成,那么我们把这个单词叫做Hat's Words。现在按照字典序,给出一系列单词,要求按照字典序输出其中的Hat's Words。
分析:
用所有的单词建立一颗字典树,对每个单词的末尾对应的节点添加标记。考虑如果一个单词被称为Hat's Words,那么把它分为两个单词后,这两个单词的结尾在字典树中对应的节点一定被标记过了。所以现在我们就枚举切割该单词的位置,判断得到的两个单词是否都能在字典树中被找到就行了。
代码:

#include <map> #include <queue> #include <math.h> #include <string> #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; #define ll long long #define ull unsigned long long #define cls(x) memset(x,0,sizeof(x)) #define clslow(x) memset(x,-1,sizeof(x)) const int wordLen=30; const int maxn=5e4+100; char s[maxn][wordLen]; struct TrieNode { bool isword; TrieNode* nex[26]; }; TrieNode* root; TrieNode* build() { TrieNode* node=new TrieNode; node->isword=false; cls(node->nex); return node; } void Insert(char* s) { int len=strlen(s); TrieNode* node=root; for(int i=0;i<len;i++){ int x=s[i]-'a'; if(node->nex[x]==NULL){ node->nex[x]=build(); } node=node->nex[x]; } node->isword=true; } bool Find(char* s) { int len=strlen(s); TrieNode* node=root; for(int i=0;i<len;i++){ int x=s[i]-'a'; if(node->nex[x]==NULL){ return false; } node=node->nex[x]; } if(node->isword) return true; return false; } void del(TrieNode* node) { for(int i=0;i<26;i++){ if(node->nex[i]!=NULL){ del(node->nex[i]); } } free(node); } char* getSub(char* s,int l,int r) { int len=strlen(s); char* t=new char[r-l+1]; for(int i=l;i<=r;i++){ t[i-l]=s[i]; } t[r-l+1]='