2 3 911 97625999 91125426 5 113 12340 123440 12345 98346
NO YES
题意:给出一些电话号码,问是否存在某些电话号码是其他号码的前缀,存在则输出NO,反之则YES
题解:字典树,加入号码的时候就判断是否在自己的前缀上已经有其他号码了,如果没有,之后再全部判断一次(也有可能前缀是之后再加入树中的)。
ps:poj也有这一题,好像是一定要静态的字典树才能过。
动态字典树:
#include<cstdio> #include<cstring> using namespace std; struct node { node *next[10]; int id; node() { memset(next,0,sizeof(next)); id=0; } }*head; bool flag; char s[10005][15]; void f(node *head) { for(int i=0;i<10;++i) if(head->next[i]!=NULL) f(head->next[i]); delete(head); } void build(char *t,node *head,int id) { int len=strlen(t),k; for(int i=0;i<len;++i) { k=t[i]-'0'; if(head->next[k]==NULL) head->next[k]=new node(); if((head->id)&&(head->id!=id)) flag=false; head=head->next[k]; } head->id=id; } int main() { int cas,n; scanf("%d",&cas); for(;cas--;) { head=new node(); flag=true; scanf("%d",&n); for(int i=1;i<=n;++i) { scanf("%s",s[i]); build(s[i],head,i); } if(flag==false) { puts("NO"); f(head); continue; } for(int i=1;i<=n;++i) { build(s[i],head,i); if(flag==false) break; } if(flag) puts("YES"); else puts("NO"); f(head); } return 0; }
静态字典树:
#include<cstdio> #include<cstring> using namespace std; struct node { int next[10]; int id; }head[100005]; bool flag; int cnt; char s[10005][15]; void build(char *t,int idx,int id) { int len=strlen(t),k; for(int i=0;i<len;++i) { k=t[i]-'0'; if(head[idx].next[k]==0) head[idx].next[k]=(cnt++); if((head[idx].id)&&(head[idx].id!=id)) flag=false; idx=head[idx].next[k]; } head[idx].id=id; } int main() { int cas,n; scanf("%d",&cas); for(;cas--;) { flag=true; cnt=1; scanf("%d",&n); memset(head,0,sizeof(head)); for(int i=1;i<=n;++i) { scanf("%s",s[i]); build(s[i],0,i); } if(flag==false) { puts("NO"); continue; } for(int i=1;i<=n;++i) { build(s[i],0,i); if(flag==false) break; } if(flag) puts("YES"); else puts("NO"); } return 0; }