链接:http://acm.hdu.edu.cn/showproblem.php?pid=1247
题意:字典序输入字典中所有字符串,然后输出哪些字符串可以由字典中的两个字符串组成。
思路就是建字典树,然后把枚举字符串,每个字符串分解成两个字符串,如果在字典树中能找到这两个字符串,就输出,break。
要记得在建树的时候每个字符串的后面打上end标记。
代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<cstring>
#include<string>
#include<cctype>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<sstream>
#include<algorithm>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int INF=1e9+7;
typedef pair<int,int> pii;
typedef long long ll;
struct trie{
int ed;
int next[26];
}tree[10001000];
char save[50010][1010];
int vis=0,cnt=0;
void Insert(char s[]){
int root=0;
for(int i=0;s[i];i++){
if(tree[root].next[s[i]-'a']){
root=tree[root].next[s[i]-'a'];
}
else{
root=tree[root].next[s[i]-'a']=++vis;
}
}
tree[root].ed=1;
}
bool Find(char s[]){
int root=0;
for(int i=0;s[i];i++){
if(!tree[root].next[s[i]-'a'])return false;
root=tree[root].next[s[i]-'a'];
}
if(tree[root].ed)return true;//如果是一个字符串的结尾
return false;
}
int main(){
// freopen("D://input.txt","r",stdin);
while(scanf("%s",save[cnt])!=EOF){
Insert(save[cnt]);
cnt++;
}
for(int k=0;k<cnt;k++){
char s1[1010],s2[1010];
for(int i=1;save[k][i];i++){
int l1=0,l2=0;
for(l1=0;l1<i;l1++)s1[l1]=save[k][l1];
s1[l1]='\0';
for(int j=i;save[k][j];j++)s2[l2++]=save[k][j];
s2[l2]='\0';
//puts(s1);puts(s2);
if(Find(s1)&&Find(s2)){
puts(save[k]);break;
}
}
}
return 0;
}