题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1671
题目大意:
给你N个字符串,判断这N个字符串中是否存在一个字符串是另一个字符串的前缀,如果存在就
输出"NO",否则输出"YES"。
思路:
建立一个字典树,将N个字符串存入字典树中,统计前缀出现次数。再查找这N个字符串,如果
出现字符串出现次数>1,则说明重复出现了两次,就输出"NO"。如果都每出现,则输出"YES"。
这道题如果每次都不删字典树,清除空间的话,会超内存。所以加上清空字典树的操作。
AC代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
char s[10010][11];
struct TrieNode
{
int Count;
struct TrieNode *Next[10];
};
TrieNode *root;
void Create()
{
root = new TrieNode;
memset(root->Next,NULL,sizeof(root->Next));
root->Count = 0;
}
void Insert(char *s)
{
TrieNode *p, *q;
p = root;
while(*s)
{
if(p->Next[*s-'0'] == NULL)
{
q = new TrieNode;
memset(q->Next,NULL,sizeof(q->Next));
q->Count = 1;
p->Next[*s-'0'] = q;
}
else
p->Next[*s-'0']->Count++;
p = p->Next[*s-'0'];
s++;
}
}
int Find(char *s)
{
TrieNode *p;
p = root;
while(*s)
{
if(p->Next[*s-'0'] == NULL)
return 0;
p = p->Next[*s-'0'];
s++;
}
return p->Count;
}
int Dele(TrieNode *p)
{
if(p == NULL)
return 0;
for(int i = 0; i < 10; ++i)
if(p->Next[i] != NULL)
Dele(p->Next[i]);
free(p);
}
int main()
{
int T,N;
scanf("%d",&T);
while(T--)
{
scanf("%d",&N);
Create();
for(int i = 0; i < N; ++i)
{
scanf("%s",s[i]);
Insert(s[i]);
}
int flag = 1;
for(int i = 0; i < N; ++i)
{
if(Find(s[i]) > 1)
flag = 0;
}
if(flag)
printf("YES\n");
else
printf("NO\n");
Dele(root);
}
return 0;
}