题意
题解
判断互不相同的字符串是否存在一个字符串为另一个字符串的前缀。
使用 T r i e Trie Trie 维护电话号码代表的字符串。对于字符串 s s s,以及任一不同的字符串 t t t,只存在 2 2 2 种可能: t t t 为 s s s 的前缀; s s s 为 t t t 的前缀。维护字符串的结尾标记信息,那么在 T r i e Trie Trie 中插入新串时,若出现父节点为另一个字符串的结尾,或者插入过程中没有动态开点,分别代表上述 2 2 2 种可能,都代表存在一个字符串为另一个字符串的前缀。
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 10005, maxl = 11, bs = 10;
int T, N, tot, trie[maxn * maxl][bs];
bool F[maxn * maxl];
bool insert(char *s)
{
int len = strlen(s), p = 0;
bool f = 0;
for (int i = 0; i < len; ++i)
{
if (F[p])
return 0;
int c = s[i] - '0';
if (!trie[p][c])
{
f = 1;
trie[p][c] = ++tot;
F[tot] = 0;
memset(trie[tot], 0, sizeof(int) * bs);
}
p = trie[p][c];
}
if (!f)
return 0;
F[p] = 1;
return 1;
}
int main()
{
scanf("%d", &T);
while (T--)
{
scanf("%d", &N);
F[0] = tot = 0;
memset(trie[0], 0, sizeof(int) * bs);
bool res = 1;
while (N--)
{
char s[maxl];
scanf("%s", s);
if (res)
res &= insert(s);
}
puts(res ? "YES" : "NO");
}
return 0;
}