POJ 3630 靜態字典樹
阿新 • • 發佈:2019-02-02
題意:給你一些電話號碼,問你是否有一個電話號碼是其他電話號碼字首
比如,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; }