http://acm.hdu.edu.cn/showproblem.php?pid=1247
第二道字典树。
先建树,然后对每个词进行查询,若串存在前缀和后缀都属于整棵字典树,则满足题意
/*
hdu 1247 字典树
此时,cnt表示以该节点到根节点组成的串的个数,而非前缀的个数(区别上一题)
注意exactly 2的情况
*/
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<algorithm>
#include<sstream>
#define eps 1e-9
#define pi acos(-1)
#define INF 0x7fffffff
#define inf -INF
#define MM 12900
#define N 50
using namespace std;
typedef long long ll;
const int _max = 5e4 + 10;
struct Trie{
Trie *next[26];
int cnt;//从根节点到该节点组成的串为前缀的个数
}*root;
void insert(char *s){
Trie *p = root,*pnew;
for(int i = 0; i < strlen(s);++ i){
int x = s[i]-'a';
if(p->next[x]==NULL){
pnew = new Trie;
pnew->cnt = 0;
for(int j = 0; j < 26; ++ j)
pnew->next[j] = NULL;
p->next[x] = pnew;
}
//else p->next[x]->cnt++;
p=p->next[x];
}
p->cnt = 1;
}
int search(char *s){
if(*s=='\0') return 0;
Trie *p = root;
for(;*s!='\0';++s){
int x = *s - 'a';
if(p->next[x]==NULL) return 0;
p=p->next[x];
}
if(p->cnt==1)return 1;//exactly 2
return 0;
}
int judge(char *s){
Trie *p = root;
for(;*s!='\0';++s){
int x = *s - 'a';
if(p->next[x]){
p = p->next[x];
if(p->cnt==1&&search(s+1)) return 1;//关键!
}
}
return 0;
}
void init(){
root = new Trie;
root->cnt = 0;
for (int i = 0;i < 26;i ++)
root->next[i] = NULL;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("input.txt","r",stdin);
#endif // ONLINE_JUDGE
char str[_max][20];//假定字符串长度不超20
init();
int i = 0;
while(gets(str[i])){
insert(str[i]);++i;
}
for(int j = 0; j<i;++ j){
if(judge(str[j])) printf("%s\n",str[j]);
}
return 0;
}