HDU 1247 (字典树)

题目链接: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.
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
word
Sample 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;
}


猜你喜欢

转载自blog.csdn.net/qq_40764917/article/details/80996497