POJ 3630 , HDU 1671 Phone List - from lanshui_Yang

       这道题也是一道找前缀的问题,很自然地要用到Trie树,但是如果用动态Trie树(即用指针开辟内存)的话,虽然在HDU上可以过(可能是HDU的数据比较水),但在POJ上会TLE , 所以这道题只能用静态Trie树。

       实现过程如下:

 

#include<iostream>

#include<cstring>

#include<string>

#include<cstdio>

#include<cmath>

#include<algorithm>

#include<queue>

#define mem(a , b) memset(a , b , sizeof(a))

using namespace std ;

const int MAXN = 1e5 + 5 ;

struct Tnode

{

    int count ;  // 记录该点是否存在单词

    int next[15] ;

    Tnode()

    {

        mem(next , 0) ;

        count = 0 ;

    }

} TT[MAXN] ;

int pan ;  // 判断标记

char s[20] ;

int cnt ;  // 序号变量

void inse(char *str)

{

    int p = 0 ; // 0 为根节点

    int id ;

    while (*str)

    {

        id = *str - '0' ;

        if(TT[p].next[id] == 0)

        {

            TT[p].next[id] = ++ cnt ;

        }

        p = TT[p].next[id] ;

        if(TT[p].count > 0)  // 此处判断是否有其他字符串 是 当前字符串 str 的前缀

        {

            pan = 1 ;

        }

        ++ str ;

    }

    int i ;

    for(i = 0 ; i < 15 ; i ++)   // 此处判断 当前字符串str 是否是其他字符串的前缀

    {

        if(TT[p].next[i] > 0)

        {

            pan = 1 ;

            return ;

        }

    }

    if(TT[p].count == 0)

        TT[p].count ++ ;

}

void dele()  // 清空原来的结点

{

    int i ;

    for( i = 0 ; i < MAXN  ; i ++)

    {

        mem(TT[i].next , 0) ;

        TT[i].count = 0 ;  // 注意此处, 千万不要忘记 !!

    }

}

int main()

{

    int T ;

    scanf("%d" , &T) ;

    while (T --)

    {

        int n ;

        scanf("%d" , &n) ;

        pan = 0 ;

        cnt = 0 ;

        while (n --)

        {

            scanf("%s" , s) ;

            inse(s) ;

        }

        if(pan == 1)

            puts("NO") ;

        else

            puts("YES") ;

        dele() ; // 清空

    }

    return 0 ;

}


 


 

你可能感兴趣的:(list)