http://acm.hdu.edu.cn/showproblem.php?pid=1671
分析:判断是否存在前缀
动态字典树:
注意动态删除内存,否则内存就吼不住了(数据中不会出现两个完全相同的号码)
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int NM=10005;
char str[NM][15];
bool flag;
struct Node{
Node *next[10];
int id;
Node(){
for(int i=0;i<10;i++)
next[i]=NULL;
id=-1;
}
};
void DelT(Node *tree)
{
for(int i=0;i<10;i++)
{
if(tree->next[i]!=NULL)
DelT(tree->next[i]);
}
delete tree;
}
void BuildT(Node *tree,char *s1,int id)
{
int len,i,t;
len=strlen(s1);
for(i=0;i<len;i++)
{
t=s1[i]-'0';
if(tree->next[t]==NULL)
tree->next[t]=new Node();
tree=tree->next[t]; //这样就不怕重复的数据
if(tree->id>-1&&tree->id!=id)
flag=false;
//tree=tree->next[t];
}
tree->id=id;
}
int main()
{
int i,n,T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
flag=true;
Node *p=new Node();
for(i=0;i<n;i++)
{
scanf("%s",str[i]);
BuildT(p,str[i],i+1);
}
if(!flag) {
printf("NO\n");
DelT(p);
continue;
}
else{
for(i=0;i<n;i++){
BuildT(p,str[i],i+1);
if(!flag) break;
}
}
if(!flag) printf("NO\n");
else printf("YES\n");
DelT(p);
}
return 0;
}
静态字典树:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int NM=10005;
char str[NM][15];
int ans;
bool flag;
struct Node{
int next[15];
int id;
}node[NM*15]; //~ans
void BuildT(char *s1,int nx,int id)
{
int i,len,t;
len=strlen(s1);
for(i=0;i<len;i++)
{
t=s1[i]-'0';
if(node[nx].next[t]==-1)
node[nx].next[t]=ans++;
if(node[nx].id>-1&&node[nx].id!=id)
flag=false;
nx=node[nx].next[t];
}
node[nx].id=id;
}
int main()
{
int T,n,i;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
memset(node,-1,sizeof(node));
ans=1;
flag=true;
for(i=0;i<n;i++)
{
scanf("%s",str[i]);
BuildT(str[i],0,i+1);
}
if(!flag) {
printf("NO\n");
continue;
}
else{
for(i=0;i<n;i++){
BuildT(str[i],0,i+1);
if(!flag) break;
}
}
if(!flag) printf("NO\n");
else printf("YES\n");
}
return 0;
}