#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define MAXN 26
using namespace std;
typedef struct Trie
{
int next[MAXN];
int cnt;
bool tail;
};
Trie f[250000];
string s[50005];
int tot;
bool cmp(const string s1,const string s2)
{
return s1.length()<s2.length();
}
void TrieInit()
{
int i;
tot=MAXN;
memset(f,0,sizeof(f));
for(i=0;i<MAXN;i++) f[0].next[i]=i+1;
}
void Insert(string s)
{
int i,j,k,l,flag;
l=s.length();
k=0;
for(i=0;i<l;i++)
{
if(f[k].next[s[i]-'a']!=0)
{
k=f[k].next[s[i]-'a'];
f[k].cnt++;
if(i==l-1) f[k].tail=1;
}
else
{
tot++;
f[k].next[s[i]-'a']=tot;
k=tot;
f[k].cnt++;
if(i==l-1) f[k].tail=1;
}
}
}
bool Find(string s)
{
int i,j,k,l,flag;
l=s.length();
k=0; flag=0;
for(i=0;i<l;i++)
{
if(f[k].next[s[i]-'a']!=0)
{
k=f[k].next[s[i]-'a'];
if(i==l-1)
{
if(f[k].tail) return 1;
else return 0;
}
}
else
{
return 0;
}
}
return 0;
}
int main()
{
int i,j,k,t,m,n;
string temp,temp2;
TrieInit();
n=0;
while(cin>>s[n])
{
Insert(s[n]);
n++;
}
for(i=0;i<n;i++)
{
temp="";
for(j=0;j<s[i].length()-1;j++)
{
temp+=s[i][j];
temp2="";
for(k=j+1;k<s[i].length();k++) temp2+=s[i][k];
if(Find(temp) && Find(temp2))
{
cout<<s[i]<<endl;
break;
}
}
}
return 0;
}
题意:
按照字典序给定n个单词,问那些单词是有其它两个单词组成的。
思路:
先把所有单词加入Trie树中,然后对每个单词进行拆分,判断拆出来的两部分能否在Trie中查询到。
代码: