题意:给出n个串,如果存在某个串是另一个串的前缀,就输出NO,否则输出YES。
题解:把所有串按字典序排序,然后建树,val[i]保存当前节点是否是某个单词的结尾,如果建树中到当前节点发现已经有值也就是val[i]!=0,就是有前缀。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100005;
int n, sz, ch[N][15], val[N];
char str[10005][15];
int cmp(const void *a, const void *b) {
return strcmp((char *)a, (char *)b);
}
bool insert(char *s, int v) {
int u = 0, len = strlen(s);
for (int i = 0; i < len; i++) {
int k = s[i] - '0';
if (!ch[u][k]) {
memset(ch[sz], 0, sizeof(ch[sz]));
val[sz] = 0;
ch[u][k] = sz++;
}
else if (val[ch[u][k]] != 0)
return false;
u = ch[u][k];
}
val[u] = v;
return true;
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
sz = 1;
memset(ch[0], 0, sizeof(ch[0]));
scanf("%d", &n);
for (int i = 0; i < n; i++)
scanf("%s", str[i]);
qsort(str, n, sizeof(str[0]), cmp);
int flag = 0;
for (int i = 0; i < n; i++) {
if (!insert(str[i], i + 1)) {
flag = 1;
break;
}
}
if (flag) printf("NO\n");
else printf("YES\n");
}
return 0;
}