给出一个电话列表,如果列表中存在其中一个号码是另一个号码的前缀这一情况,那么就称这个电话列表是不兼容的。
假设电话列表如下:
Emergency 911
Alice 97 625 999
Bob 91 12 54 26
在此例中,报警电话号码(
911
)为 Bob 电话号码(91 12 54 26
)的前缀,所以该列表不兼容。输入格式
第一行输入整数 tt,表示测试用例数量。
对于每个测试用例,第一行输入整数 nn,表示电话号码数量。
接下来 nn 行,每行输入一个电话号码,号码内数字之间无空格,电话号码不超过 1010 位。
输出格式
对于每个测试用例,如果电话列表兼容,则输出
YES
。否则,输出
NO
。数据范围
1≤t≤401≤t≤40,
1≤n≤100001≤n≤10000输入样例:
2 3 911 97625999 91125426 5 113 12340 123440 12345 98346
输出样例:
NO YES
/*
将每个读入的电话号码都插入trie树中,然后判断当前插入的数是否在之前出现过
*/
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int N = 10010;
bool f[N * 10];
char str[15];
int son[N * 10][10], idx;
bool insert(char str[])
{
int p = 0;
bool has_new = false, has_find = false;
for (int i = 0; str[i]; i ++ )
{
int u = str[i] - '0';
if (!son[p][u])
{
son[p][u] = ++ idx;
has_new = true;
}
p = son[p][u];
if (f[p]) has_find = true;
}
f[p] = true;
return !has_new || has_find;
}
int main()
{
int T;
cin >> T;
while (T -- )
{
int n;
scanf("%d", &n);
bool is_repeat = false;
idx = 0;
memset(f, false, sizeof f);
memset(son, 0, sizeof son);
for (int i = 0; i < n; i ++ )
{
scanf("%s", str);
if (insert(str))
{
is_repeat = true;
}
}
if (is_repeat) puts("NO");
else puts("YES");
}
return 0;
}