题目链接
题目描述(Description)
给出一列电话号码,判断这些号码里时候有的号码是另一个号码的前缀,如果是,则此号码不符合条件(输出NO),否则输出YES。
分析(Analysis)
属于字典树的应用。这里的branch
是0-9
这10个字符。设置flag
作为判断的标志。
分两步:
- 当前插入单词
word
是否为之前字符串的前缀 - 之前的字符串是否为
word
的前缀
代码(Code)
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=100001;
const int branch=10;
struct tree_node{
bool end;
tree_node *next[branch];
}root,node[maxn];
int p;
bool flag;
void insert(char *word)
{
tree_node *location=&root;
bool newflag=false;
while(*word){
if(location->end)//前面的串是word的前缀
{
flag=false;
return;
}
if(location->next[*word-'0']==NULL){//建立新的分支,word不是之前串的前缀
newflag=true;
node[p].end=false;
memset(node[p].next,NULL,sizeof(node[p].next));
location->next[*word-'0']=&node[p++];
}
location=location->next[*word-'0'];
word++;
}
location->end=true;
if(!newflag)//word是之前串的前缀
flag=false;
}
int main()
{
int t,n;
char s[11];
scanf("%d",&t);
while(t--){
scanf("%d",&n);
p=0;
flag=true;
memset(root.next,NULL,sizeof(root.next));
while(n--){
scanf("%s",s);
if(flag)//没有出现一个字符串是另一个字符串的前缀的情况下插入字典树
insert(s);
}
if(flag)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}