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



你可能感兴趣的:(静态Trie树)