这道题也是一道找前缀的问题,很自然地要用到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 ; }