电话号码 【trie树】
版权声明:长风原创 https://blog.csdn.net/u012846486/article/details/37941077
电话号码
查看 提交 统计 提问
总时间限制: 1000ms 内存限制: 65536kB
描写叙述给你一些电话号码。请推断它们是否是一致的,即是否有某个电话是还有一个电话的前缀。
比方:
Emergency 911
Alice 97 625 999
Bob 91 12 54 26
在这个例子中,我们不可能拨通Bob的电话,由于Emergency的电话是它的前缀。当拨打Bob的电
话时会先接通Emergency,所以这些电话号码不是一致的。
输入
第一行是一个整数t。1 ≤ t ≤ 40,表示測试数据的数目。
每一个測试例子的第一行是一个整数n,1 ≤ n ≤ 10000。其后n行每行是一个不超过10位的电话号码。
输出
对于每一个測试数据,假设是一致的输出“YES”,假设不是输出“NO”。
例子输入
2
3
911
97625999
91125426
5
113
12340
123440
12345
98346
例子输出
NO
YES
简单trie树。注意两种情况:先插入短串再插入长串和先插入长串再插入短串。
#include <stdio.h> #include <string.h> #include <stdlib.h> struct Node{ struct Node *next[10]; int isCover, isEnd; }; int ok; void clean(Node *p) { memset(p->next, 0, sizeof(p->next)); p->isCover = p->isEnd = 0; } void insert(char *str, Node *root) { Node *p = root; int id; while(*str){ id = *str - '0'; if(p->next[id] == NULL){ p->next[id] = (Node *)malloc(sizeof(Node)); clean(p->next[id]); } p = p->next[id]; if(p->isEnd) ok = 0; ++p->isCover; ++str; } if(p->isCover > 1) ok = 0; p->isEnd = 1; } void DELETE(Node *p) { for(int i = 0; i < 10; ++i) if(p->next[i]) DELETE(p->next[i]); free(p); } int main() { int t, n; char str[12]; scanf("%d", &t); while(t--){ Node *root = (Node *)malloc(sizeof(Node)); scanf("%d", &n); clean(root); ok = 1; while(n--){ scanf("%s", str); if(ok) insert(str, root); } printf(ok ?
"YES\n" : "NO\n"); DELETE(root); } return 0; }