电话列表[字典树]
给出一个电话列表,如果列表中存在其中一个号码是另一个号码的前缀这一情况,那么就称这个电话列表是不兼容的。
假设电话列表如下:
·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; } }
追求吾之所爱