题意:给你一堆单词,找出其中能够被其他两个单词构成的单词。按字典序输出。(没必要考虑字典序问题,因为输入就是按字典序输入)
思路:用这一堆单词构造一颗字典树并用数组保存这些单词,然后再依次对每个单词枚举切成两个单词的情况,查找是否切成的两部分都能在字典树中被找到。
AC代码:
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<string>
#include<queue>
#include<vector>
#include<map>
using namespace std;
const int mx=1000010;
struct Trie{
int ch[mx][26];
bool v[mx];
int t;
void init(){t=1;v[0]=0;memset(ch[0],0,sizeof(ch[0]));}
void add(char *s)
{
int u=0,n=strlen(s);
for(int i=0;i<n;i++)
{
int id=s[i]-'a';
if(ch[u][id]==0)
{
ch[u][id]=t;
memset(ch[t],0,sizeof(ch[t]));
v[t++]=0;
}
u=ch[u][id];
}
v[u]=1;
}
bool search(char *s)
{
int u=0,n=strlen(s);
for(int i=0;i<n;i++)
{
int id=s[i]-'a';
if(ch[u][id]==0) return 0;
u=ch[u][id];
}
return v[u];
}
};
Trie a;
char w[30100][50];
int main()
{
a.init();
int num=0;
while(gets(w[num]))
{
a.add(w[num++]);
}
for(int j=0;j<num;j++)
{
int l=strlen(w[j]);
for(int i=1;i<l;i++)
{
char st1[50],st2[50];
strncpy(st1,w[j],i);
st1[i]=0;
strncpy(st2,w[j]+i,l-i);
st2[l-i]=0;
if(a.search(st1)&&a.search(st2)) {printf("%s\n",w[j]);break;}
}
}
return 0;
}