题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1247
hat’s word is a word in the dictionary that is the concatenation of exactly two other words in the dictionary.
You are to find all the hat’s words in a dictionary.
Input
Standard input consists of a number of lowercase words, one per line, in alphabetical order. There will be no more than 50,000 words.
You are to find all the hat’s words in a dictionary.
Only one case.
Output Your output should contain all the hat’s words, one per line, in alphabetical order. Sample Input
a ahat hat hatword hziee wordSample Output
ahat hatword
题意:
给你好多个单词,让你在这些单词找出能拆分成两个不同且在这些单词中出现的单词的单词..........。如:给你3个单词 a,ahat,hat,你就要找的ahat
思路:
刚学字典树,以为插入后要遍历一遍树,然后输出,然后感觉太难了,这个代码等以后再说吧。其实不用遍历树,把你的那些单词重新在字典树里再找一遍就行了。值得注意的是,满足条件的单词,不仅要满足被分开的两个单词存在于字典树中,还要查找到最后一位的字母是树的一个结尾。比如abc,abcde,def,这组测试数据,答案应该是空。
AC代码(数组模拟):
PS:有点小快0n0
Time | 15ms |
---|---|
Memory | 7108kB |
Length | 1241 |
#include <cstring>
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
char ss[50005][55];
int ls;
int trie[50005][26] ;
int tot,val[50005] ;
void trieIn( char* x )
{
int root = 0 ;
int id ;
for( int i=0; i<strlen(x); i++ )
{
id = x[i] - 'a' ;
if( !trie[root][id] )
trie[root][id] = ++tot;
root = trie[root][id];
}
val[root] = 1;
}
bool trieAS(char* x,int k )
{
int root = 0 ;
int id;
for( int i=k+1; i<strlen(x); i++ )
{
id = x[i] - 'a';
if( trie[root][id]==0 ) return false;
root = trie[root][id];
}
if( val[root]==1 )
return true;
else return false;
}
bool isright( char* x )
{
int ans = 0 ;
int root = 0 ;
int id ;
for( int i=0; i<strlen(x); i++ )
{
id = x[i] - 'a';
root = trie[root][id];
if( val[root] == 1 && i!=strlen(x)-1 )
{
if( trieAS(x,i) ) return true;
}
}
return false;
}
int main()
{
ls = tot = 0 ;
while( ~scanf("%s",&ss[ls]) )
{
trieIn(ss[ls++]);
}
for( int i=0; i<ls; i++ )
{
if( isright( ss[i] ) )
printf("%s\n",ss[i]);
}
return 0;
}
AC代码:(指针模拟)
//emmmmmmmmm,黑人问号?
Time |
31ms |
---|---|
Memory | 12248kB |
Length | 1253 |
#include <cstring>
#include <cstdio>
#include <iostream>
using namespace std;
char cs[50005][55];
struct Trie
{
int id;
bool isWord;
Trie* node[26];
Trie()
{
id=0,isWord=false;
memset(node,0,sizeof(node));
}
}*root;
void TrieIn( char* x )
{
Trie *p,*temp;
p = root ;
for( int i=0; x[i]; i++ )
{
if( p->node[x[i]-'a'] == NULL )
{
temp = new Trie;
p->node[x[i]-'a'] = temp;
}
p = p->node[x[i]-'a'] ;
}
p->isWord = true;
}
bool trieSE( char* x, int k )
{
Trie *p;
p = root ;
for( int i=k+1; x[i]; i++ )
{
if( p->node[x[i]-'a'] == NULL ) return false;
p = p->node[x[i]-'a'];
}
return p->isWord;
}
bool isright( char* x )
{
Trie *p;
p = root ;
for( int i=0; x[i]; i++ )
{
p = p->node[x[i]-'a'];
if( p->isWord == true && i!=strlen(x)-1 )
{
if( trieSE(x,i)) return true;
}
}
return false;
}
int main()
{
int ls=0;
root = new Trie ;
while( ~scanf("%s",&cs[ls]) )
{
TrieIn(cs[ls++]);
}
for( int i=0; i<ls; i++ )
{
if( isright( cs[i] ) )
printf("%s\n",cs[i]);
}
return 0;
}