2 3 911 97625999 91125426 5 113 12340 123440 12345 98346
NO YES
题意 : 给出n个字符串 , 且任意两个字符串不存在前缀关系,那么输出yes, 否则输出no 。
思路 : 建立Trie ,val[]的值代表字符串是否为结束点 ,非0 代表是,0代表不是 。 然后再遍历n个字符串 , 计算每一个字符串的val[],统计出val[]的个数,假如val[]非0的个数大于1,说明这个串存在前缀,返回不满足。
#include <string.h>
#include <stdio.h>
int ch[100050][11];
int val[100050];
int sz;
int idx(char c) { return c-'0'; }
void inser(char *s , int v) {
int u=0 , n=strlen(s);
for(int i=0;i<n;i++) {
int c=idx(s[i]);
if( !ch[u][c] ) {
// memset(ch[sz] ,0 ,sizeof(sz));
val[sz]=0;
ch[u][c]=sz++;
}
u=ch[u][c];
}
val[u]=v;
}
int Find(char *s ) {
int i, n=strlen(s) , u=0 ,cnt=0;
for(i=0;i<n;i++) {
int c=idx(s[i]);
u=ch[u][c];
if(val[u] != 0) cnt++;
}
if(cnt>1) return 0;
else return 1;
}
char a[10005][11];
int main()
{
int T,n,i;
scanf("%d%*c",&T);
while(T--) {
sz=1;
memset(val,0,sizeof(val));
memset(ch,0,sizeof(ch));
scanf("%d%*c",&n);
for(i=0; i<n;i++) {
scanf("%s",a[i]);
inser( a[i], 1 );
}
for(i=0;i<n;i++) {
if(!Find(a[i])) {
printf("NO\n");
break;
}
}
if(i == n) printf("YES\n");
}
return 0;
}
字典树 Trie (HDU 1671),布布扣,bubuko.com
原文:http://blog.csdn.net/u013923947/article/details/28901865