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

Time15ms
Memory7108kB
Length1241

#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
Memory12248kB
Length1253
  

#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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值