HDU1671 - Phone List(Trie树)
题目大意
给定一些电话号码,判断是否有电话号码是其他电话号码的前缀
题解
裸Trie树嘛~~~~只需要一个插入过程即可,假设X是Y的前缀,在插入的过程中有两种情况,X在Y之前插入,那么在插入Y的时候经过了X的尾结点,插入的过程中判断下即可,还有一种情况就是X在Y之后插入,那么插入X的时候肯定不需要插入新结点~~~也记录一下即可~~~~~被坑了好多次,先是没有考虑第二种情况,改了之后RE,然后脑残的发现把数字字符转换为数字的时候是-‘a’…改完就AC了。。。
代码:
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> using namespace std; const int maxnode=111111; const int sigma_size=11; bool flag; int ans; struct Trie { int ch[maxnode][sigma_size]; int val[maxnode]; int sz; void clear(){sz=1;memset(val,0,sizeof(val));memset(ch[0],0,sizeof(ch[0]));} int idx(char c){return c-'0';} void insert(char *s) { int u=0,n=strlen(s),ans=0; for(int i=0;i<n;i++) { int c=idx(s[i]); if(!ch[u][c]) { memset(ch[sz],0,sizeof(ch[sz])); ch[u][c]=sz++; ans++; } else if(val[ch[u][c]]) flag=true; u=ch[u][c]; } if(!ans) flag=true; val[u]++; } }; Trie trie; int main() { int T; scanf("%d",&T); while(T--) { trie.clear(); char num[15]; int n; flag=false; scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%s",num); if(flag) continue; trie.insert(num); } if(flag) printf("NO\n"); else printf("YES\n"); } return 0; }