电话列表[字典树]

给出一个电话列表,如果列表中存在其中一个号码是另一个号码的前缀这一情况,那么就称这个电话列表是不兼容的。

假设电话列表如下:

·Emergency 911
·Alice 97 625 999
·Bob 91 12 54 26

在此例中,报警电话号码(911)为Bob电话号码(91 12 54 26)的前缀,所以该列表不兼容。

输入格式

第一行输入整数t,表示测试用例数量。

对于每个测试用例,第一行输入整数n,表示电话号码数量。

接下来n行,每行输入一个电话号码,号码内数字之间无空格,电话号码不超过10位。

输出格式

对于每个测试用例,如果电话列表兼容,则输出”YES”。

否则,输出”NO”。

数据范围

1≤t≤40<?XML:NAMESPACE PREFIX = "[default] http://www.w3.org/1998/Math/MathML" NS = "http://www.w3.org/1998/Math/MathML" />1≤t≤40,
1≤n≤100001≤n≤10000

输入样例:
2
3
911
97625999
91125426
5
113
12340
123440
12345
98346
输出样例:
NO
YES


#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
const int N = 1e5 + 5;//注意这个取值
int tire[N][10], tot, cnt[N];
void insert(string s, bool &flag) {
    if(flag == false) return;
	int p = 0;
	for(int i = 0; i < s.size(); ++ i) {
		int &c = tire[p][s[i] - '0'];
		if(!c) c = ++tot;
		if(cnt[p]) {
			flag = false;
		}
		p = c;
	}
	cnt[p] ++;
}

int main() {
	int t;
	cin >> t;
	while(t --) {
		int n;
		bool flag = true;
		cin >> n;
		vector<string> s(n);

		for(int i = 0; i < n; ++ i)
			cin >> s[i];

		sort(s.begin(), s.end());

		for(auto i : s) insert(i, flag);
		if(flag) puts("YES");
		else puts("NO");
		memset(cnt, 0, sizeof cnt);
		memset(tire, 0, sizeof tire);
		tot = 0;
	}
}
posted @ 2020-07-27 17:12  ACWink  阅读(88)  评论(0编辑  收藏  举报