题意:给你一堆数字串 问你其中是否有一个串是另一个串的前缀
思路:又是一道裸的字典树。。。对于每一个数字串 先判断是否是其它字符串的前缀或者它是别的字符串的前缀 如果是 后面就不用再判断了 如果不是 就把这个串存入字典树中 继续下面的判断
#include <cstdio>
#include <cstring>
using namespace std;
#define REP( i, a, b ) for( int i = a; i < b; i++ )
struct Trie{
int va;
Trie *next[10];
Trie(int va) : va(va) { REP(i, 0, 10) next[i] = NULL; }
};
void CreatTrie(Trie *root, char *str){
int len = strlen(str);
Trie *p = root, *q;
REP(i, 0, len){
int id = str[i] - '0';
if(p -> next[id] == NULL){
q = new Trie(1);
p -> next[id] = q;
p = p -> next[id];
}
else
p = p -> next[id];
}
p -> va = -1;
}
bool FindTrie(Trie *root, char *str){
int len = strlen(str);
Trie *p = root;
REP(i, 0, len){
int id = str[i] - '0';
if(p -> next[id] == NULL) return false;
if(p -> next[id] -> va == -1) return true;
//存在一个串是这个串的前缀
p = p -> next[id];
}
return true;//这个串是其它串的前缀
}
void DelTrie(Trie *root){
if(root == NULL) return;
REP(i, 0, 10) DelTrie(root -> next[i]);
delete[] root;
}
void solve(){
int n, flag = 1;
char str[15];
Trie *root = new Trie(0);
scanf("%d", &n);
REP(i, 0, n){
scanf("%s", str);
if(flag){
if(FindTrie(root, str)) flag = 0;
CreatTrie(root, str);
}
}
if(flag) printf("YES\n");
else printf("NO\n");
DelTrie(root);
}
int main()
{
//freopen("in.txt", "r", stdin);
int T;
scanf("%d", &T);
while(T--) solve();
return 0;
}