题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=1247
题目大意:给出你很多单词,求哪些单词是由这里其他单词(2个)连接组成的,注意!2个相同的单词连接也可以的!
字典树,将单词分为两段,共有len-1中方法,如果两个都有则输出
代码如下:
#include <iostream>
#include <vector>
#include <list>
#include <deque>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <cctype>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
using namespace std;
const int N=26;
typedef long long LL;
char xh[50005][20];
struct Trie
{
Trie *next[N];
int v;
Trie()
{
v=0;
for(int i=0;i<N;i++)
next[i]=NULL;
}
}*root;
void setroot()
{
root=(Trie *)malloc(sizeof(Trie));
for(int i=0;i<N;i++)
root->next[i] = NULL;
}
void createTrie(char *str)
{
int i,j,id;
int len=strlen(str);
Trie *p=root;
for(i=0;i<len;i++)
{
id=str[i]-'a';//这个地方依据题意来定
if(p->next[id]==NULL)
{
p->next[id]=new Trie();
}
p=p->next[id];
}
p->v=1;//末尾节点
}
bool findTrie(char *str)
{
int i,id;
int len=strlen(str);
Trie *p=root;
for(i=0;i<len;i++)
{
id=str[i]-'a';
p=p->next[id];
if(p==NULL) //若为空集,表示不存以此为前缀的串
return false;
}
if(p->v==1)
{
return true;
}
return false; //此串是字符集中某串的前缀
}
void dealTrie(Trie *T)
{//若果有多组数据-多棵树,那么要释放内纯
int i;
if(T==NULL)
return ;
for(i=0;i<N;i++)
if(T->next[i]!=NULL)
dealTrie(T->next[i]);
free(T);//释放
}
char a[105],b[105];
int main()
{
int i,j,n;
root=new Trie();
n=0;
while(scanf("%s",xh[n])!=EOF)
{
createTrie(xh[n]);
n++;
}
for(i=0;i<n;i++)
{
int len=strlen(xh[i]);
for(j=0;j<len;j++)
{
memset(a,'\0',sizeof(a));
memset(b,'\0',sizeof(b));
strncpy(a,xh[i],j);
strncpy(b,xh[i]+j,len-j);
if(findTrie(a)&&findTrie(b))
{
printf("%s\n",xh[i]);
break;
}
}
}
dealTrie(root);
return 0;
}