POJ 3630 静态字典树
题意:给你一些电话号码,问你是否有一个电话号码是其他电话号码前缀
比如,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; }