Phone List
共t组数据,给定n个长度不超过10的字符串,问其中是否存在两个数S,T,使得S是T的前缀。
存在则输出NO,不存在输出YES
输出样例#1:
这是代码
NO YES
此题转自洛谷UVA11362
Trie树模板题,可以一边构建Trie树一边判断答案,详见代码。
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<cmath> using namespace std; inline int read() { int f=1,x=0; char ch=getchar(); while(ch<'0' || ch>'9') {if(ch=='-') f=-1; ch=getchar();} while(ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} return x*f; } int T,n,cnt=1; bool flag; int ove[100005],pre[100005],tree[100005][15]; char a[100005]; /* tree是trie树 ove[i]表示以i为结点的数 pre[i]表示i结点的出边数 */ void insert(char *s)//插入+查找 { int len=strlen(s),p=1; for(int i=0;i<len;i++) { int c=s[i]-'0';//若是字母串,变为-'a' if(tree[p][c]==0)//若当前结点p的子节点中没有要找的c,则将c插入 tree[p][c]=++cnt; p=tree[p][c];//继续查找 pre[p]++; if(ove[p])//某串是该串的前缀 { flag=1; break; } } ove[p]=1;//标记该串在结点p结束 if(pre[p]>1)//该串是某串的前缀 flag=1; } int main() { T=read(); int i,j; while(T--) { memset(tree,0,sizeof(tree)); memset(ove,0,sizeof(ove)); memset(pre,0,sizeof(pre)); flag=0; cnt=1; n=read(); for(i=1;i<=n;i++) { scanf("%s",a); if(!flag) insert(a); } if(flag) printf("NO "); else printf("YES "); } return 0; }