题意:给你一些电话号码,问你是否有一个电话号码是其他电话号码前缀
比如,911 和911584这两个号码,911是911584的前缀
解题思路:经过pork大神的指导,估计时间如下,一共有10000个电话号码插入,每个号码最长10位,如果每次插入最差就是开辟10个新的节点,那就是10000*10*10个,一百W,如果有new开辟的话,时间耗费严重,超时是必然的,那么用静态数组,提前开辟100W个,用的时候就把它提出来。
检测的时候先按长度排序,举个discuss的反例
2 2 1 12 2 12 1 NO NO必须先保证长度小的先被插入字典树里面,这样长度长的才能检测出来
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
struct Dictree
{
bool in;
struct Dictree *next[10];
}node[1000000];
Dictree root;
int cmp(const void *a,const void *b)
{
char *p1,*p2;
p1=(char *)a;
p2=(char *)b;
return strlen(p1)-strlen(p2);
}
int tot;
char s[10005][12];
bool reflect;
void create_tree();
void insert(char *);
int main()
{
int cas,n,i;
for(scanf("%d",&cas);cas;cas--)
{
reflect=false;
create_tree();
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%s",s[i]);
qsort(s,n,sizeof(s[0]),cmp);
for(i=0;i<n;i++)
if(!reflect) insert(s[i]);
if(reflect) printf("NO\n");
else printf("YES\n");
}
return 0;
}
void create_tree()
{
root.in=false;
tot=0;
memset(root.next,NULL,sizeof(root.next));
}
void insert(char *s)
{
int i;
struct Dictree *p;
p=&root;
for(i=0;s[i];i++)
{
if(p->next[s[i]-'0']==NULL)
{
node[tot].in=false;
memset(node[tot].next,NULL,sizeof(node[tot].next));
p->next[s[i]-'0']=&node[tot++];
}
p=p->next[s[i]-'0'];
if(p->in) reflect=true;
}
p->in=true;
}