HDU1247 Hat’s Words (字典树)

链接: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;
}


你可能感兴趣的:(HDU1247 Hat’s Words (字典树))