HDU 1671 Phone List(字典树Trie)
http://acm.hdu.edu.cn/showproblem.php?pid=1671
题意:
给你多个由0-9构成的字符串集合,问你这个集合中是否有一个字符串是其他字符串的前缀?
分析:
直接构造字典树,然后一一插入每个字符串,判断是否有比当前字符串短或长的同一路径的字符串已经在树中了.
注意:字典树中如果该节点是一个电话号码的尾节点,那么val值为1,否则为0.
AC代码:
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; const int maxnode=100000+1000; const int sigma_size=10; struct Trie { int ch[maxnode][sigma_size]; int val[maxnode];//非单词节点为0,单词节点为1 int sz; void init() { sz=1; val[0]=0; memset(ch[0],0,sizeof(ch[0])); } bool insert(char *s) { bool ok=true; int n=strlen(s),u=0; for(int i=0;i<n;i++) { int id=s[i]-'0'; if(ch[u][id]==0) { ch[u][id]=sz; val[sz]=0; memset(ch[sz],0,sizeof(ch[sz])); sz++; } u=ch[u][id]; if(val[u]>0)//存在当前插入串s的前缀 ok=false; } val[u]=1; if(ok) { for(int i=0;i<sigma_size;i++) if(ch[u][i]!=0)//存在包含当前插入串的长串 { ok=false; break; } } return ok; } }; Trie trie; char word[20]; int main() { int kase; scanf("%d",&kase); while(kase--) { int n; scanf("%d",&n); trie.init(); bool ok=true; for(int i=0;i<n;i++) { scanf("%s",word); if(ok) ok=trie.insert(word); } if(ok)printf("YES\n"); else printf("NO\n"); } return 0; }