hdu 1251 前缀树

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1251

    普通trie树,只是在构建的时候统计出每个节点儿子的个数,最后直接匹配每个前缀,输出最后一个前缀字符在树中儿子的个数加一(其本身)即可。

    纠结的是题目没给数据范围,tree数组开100010 RE,开200010 还是RE,一狠心开了500010,果断AC。。。

 

代码:

 

 

#include<iostream>
#include<cstring>
#include<cstdio>
using  namespace std ;
int num ;
int ans ;
struct node{
     int n ;
     int next[ 30] ;
     void init(){
        memset(next, 0, sizeof(next)) ;
        n= 0 ;
    }
}tree[ 500010] ;

void insert( char a[]){
     int index= 0 ;
     int len=strlen(a) ;
     for( int i= 0;i<len;i++){
         if(tree[index].next[a[i]- ' a ']== 0){
            tree[++num].init() ;
            tree[index].next[a[i]- ' a ']=num ;
            index=num ;
            tree[index].n= 1 ;   // 新节点没有儿子,但其本身也为本身的前缀
        }
         else{
            index=tree[index].next[a[i]- ' a '] ;
            tree[index].n ++ ;  // 每匹配一个字符,儿子个数增一
        }
    }
}
int find( char a[]){
     int index= 0 ;
     int len=strlen(a) ;
     if(len== 0)   return  0 ;
     for( int i= 0; i<len; i++){
         if(tree[index].next[a[i]- ' a ']== 0)
             return  0 ;
         else
            index=tree[index].next[a[i]- ' a '] ;
    }
     return tree[index].n ;
}
int main(){
     char str[ 15] ;
     int t= 0 ;
    tree[ 0].init() ;
    num =  0 ;
    ans =  0 ;
     while(gets(str),strcmp(str, "")!= 0)       // 获取以空行区分的字符串
        insert(str) ;
     while(scanf( " %s ", str)!=EOF)
        cout << find(str) << endl ;
     return  0 ;
}

 

你可能感兴趣的:(HDU)