Hats’World

Problem Description:
A hat’s word is a word in the dictionary that is the concatenation of exactly two other words in the dictionary.
You are to find all the hat’s words in a dictionary.
Input:
Standard input consists of a number of lowercase words, one per line, in alphabetical order. There will be no more than 50,000 words.
Only one case.
Output:
Your output should contain all the hat’s words, one per line, in alphabetical order.
Sample Input:
a
ahat
hat
hatword
hziee
word
Sample Output:
ahat
hatword
题目大意:
给定一组单词,让你找到一个单词,使得这个单词由这组单词中出现过的两个单词构成。
例:ahat由a和hat构成,而a和hat在这组单词中出现过。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=50010;
struct node
{
int next[27];
int b;
}tree[maxn];
int tot=1,sum,top,stack[maxn];
char s[maxn][27];
void build_tree(int l,char s[])
{
int now=0;
for(int i=0;i<l;i++)
{
int x=s[i]-96;
if(tree[now].next[x])
now=tree[now].next[x];
else
{
tree[now].next[x]=++sum;
now=sum;
}
}
tree[now].b=true;
}
int can(int l,char s[])
{
int i=0,now=0,top=0;
for(int i=0;i<l;i++)
{
int x=s[i]-96;
if(tree[now].next[x])
now=tree[now].next[x];
else return 0;
if(tree[now].b&&s[i])
stack[top++]=i+1;
}
while(top)
{
int now=0;
bool flag=1;
int x=stack[--top];
while(s[x])
{
if(!tree[now].next[s[x]-96])
{
flag=0;
break;
}
now=tree[now].next[s[x]-96];
x++;
}
if(flag&&tree[now].b)
return 1;
}
return 0;
}
int main()
{
while(gets(s[tot])&&strlen(s[tot]))
{
int len=strlen(s[tot]);
build_tree(len,s[tot]);
tot++;
}
for(int i=1;i<=tot;i++)
{
int len=strlen(s[i]);
if(can(len,s[i]))
cout<<s[i]<<endl;
}
return 0;
}