您的位置:首页 > 其它

hdu1247 hat's words 字典树

2016-08-15 10:48 429 查看
/*
题目描述:给出n(n<5,000)个单词,其中被称为hatword的单词满足这个词恰好由给出的词中的两个单词
首位相接而成,现要求输出给出单词中的hatword

方法:应用字典树解决问题,先将单词全部插入完成建树,然后利用dfs进行查询,具体查询方式见注释
*/
#pragma warning(disable:4786)
#pragma comment(linker, "/STACK:102400000,102400000")
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<cmath>
#include<string>
#include<sstream>
#define LL long long
#define FOR(i,f_start,f_end) for(int i=f_start;i<=f_end;++i)
#define mem(a,x) memset(a,x,sizeof(a))
#define lson l,m,x<<1
#define rson m+1,r,x<<1|1
using namespace std;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const double PI = acos(-1.0);
const double eps=1e-8;
const int maxn = 100 + 5;
const int maxnode = 5e4 + 5;
const int sigma_size = 26;
char s[maxnode][maxn];
struct Trie
{
int ch[maxnode][sigma_size];
int val[maxnode];
int sz;
Trie()  { sz = 1;       mem(ch , 0);  }
int idx(char c)     {return c - 'a';}

void insert(char *s ,int v)
{
int u = 0 , n = strlen(s);
for(int i = 0 ; i<n ; i++){
int c = idx(s[i]);
if(!ch[u][c]){
mem(ch[sz] , 0);
val[sz] = 0;
ch[u][c] = sz++;
}
u = ch[u][c];
}
val[u] = v;
}

bool find(char * s )
{
int u = 0 , n  = strlen(s);
for(int i = 0 ; i<n ; i++){
int c = idx(s[i]);
if(!ch[u][c])       return false;
u = ch[u][c];
}
if(!val[u])     return false;
return true;
}

bool dfs(char * s , int sum)
{
if(sum==1){
if(find(s))     return true;
else             return false;
}
int u = 0 , n = strlen(s);
for(int i = 0 ; i<n ; i++){
int c = idx(s[i]);
u = ch[u][c];
if(i!=n-1&&val[u]!=0&&dfs(s+i+1 , sum + 1))  //前两个条件指s[0]——s[i]构成的单词在trie里,后一条件指s[i+1]——s[n-1]在trie里
return true;
}
return false;
}

};
Trie t;
int main()
{
int n = 1;
while(scanf("%s",s
)!=EOF){
t.insert(s[n++] , 1)  ;
}
for(int i  = 1 ; i < n ; i++){
if(t.dfs(s[i] , 0))    printf("%s\n",s[i]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: