// poj4 3630 Phone List
// 题意: 给一组互不相同的号码,问其中是否有号码是另一号码的前缀
#include <iostream> // trie树
using namespace std ;
struct Node
{
Node *next[10]; //数字0-9
int vis; //记录该节点所代表的号码是否有被访问过
}table[100000];
Node *root;
int cur;
void init()
{
//trie树的根结点不包含字符信息
root=&table[0];
for(int i=0;i<10;++i)
root->next[i]=NULL;
cur=1;
}
int prefix(char ch[]) //若出现前缀情况则返回 1
{
Node* p=root;
int tag=1; //假定存在前缀
for(int i=0;ch[i];++i)
{
int j=ch[i]-'0';
if(p->next[j]==NULL) //说明不可能存在前缀
{
tag=0;
Node* q=&table[cur++];
for(int k=0;k<10;++k)
q->next[k]=NULL;
q->vis=0;
p->next[j]=q;
}
p=p->next[j]; //继续搜索下去
if(p->vis) //说明存在前缀
return 1;
}
p->vis=1;
return tag;
}
int main()
{
int cases,n;
cin>>cases;
while(cases--)
{
init();
int suc=1;
char ch[11];
cin>>n;
while(n--)
{
scanf("%s",ch);
if( suc && prefix(ch) )
suc=0;
}
if(suc)
printf("YES\n");
else
printf("NO\n");
}
return 0 ;
}
// poj4 3630 Phone List
#include <iostream> // trie树
using namespace std ;
struct Node
{
int next[10]; //替换掉上面的Node *next[10];
int vis; //记录该节点所代表的号码是否有被访问过
}table[100000];
int cur;
void init()
{
memset(table[0].next,-1,sizeof(table[0].next));
cur=1;
}
int prefix(char ch[]) //若出现前缀情况则返回 1
{
Node* p=&table[0]; //table[0]作为根节点
int tag=1; //假定存在前缀
for(int i=0;ch[i];++i)
{
int j=ch[i]-'0';
if(p->next[j]==-1) //说明不可能存在前缀
{
tag=0;
p->next[j]=cur++;
Node* q=&table[p->next[j]];
for(int k=0;k<10;++k)
q->next[k]=-1;
q->vis=0;
}
p=&table[p->next[j]]; //继续搜索下去
if(p->vis) //说明存在前缀
return 1;
}
p->vis=1;
return tag;
}
int main()
{
int cases,n;
cin>>cases;
while(cases--)
{
init();
int suc=1;
char ch[11];
cin>>n;
while(n--)
{
scanf("%s",ch);
if( suc && prefix(ch) )
suc=0;
}
if(suc)
printf("YES\n");
else
printf("NO\n");
}
return 0 ;
}