//hdu1671 字典树(模板题) #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define maxn 10 //子树的数量 using namespace std; struct Trie { int v;//该字符出现的次数,叶子字符出现的次数为-1 Trie *next[maxn]; }; Trie *root; void createTrie(char *str) //传入字符串,建字典树 { int len = strlen(str); Trie *p = root, *q; for (int i = 0; i < len; i++) { int id = str[i] - '0';//id为字符编号 if (p->next[id] == NULL) {//之前还没录入过该字符, q = (Trie *)malloc(sizeof(Trie));//要为该字符开一块空间 q->v = 1; for (int j = 0; j < maxn; j++) q->next[j] = NULL; p->next[id] = q; p = p->next[id]; } else{ p->next[id]->v++;//出现次数加一 p = p->next[id]; } } p->v = -1;//叶子字符出现的次数为-1 } int findTrie(char *str)//传入字符串str与已有字符串比较 { int len = strlen(str); Trie *p = root; for (int i = 0; i < len; i++) { int id = str[i] - '0'; p = p->next[id]; if (p == NULL)//前i(i<len)个元素不相同,返回0表示没有相同前缀 return 0; if (p->v == -1)//所有元素相同,返回-1表示 return -1; } return -1; } int del(Trie *T)//清空,释放空间(人工走一遍有助于理解) { if (T == NULL)//字典树T 为空返回0 return 0; for (int i = 0; i < maxn; i++) { if (T->next[i] != NULL) del(T->next[i]); } free(T); return 0; } int main() { char str[15]; int nCases, nNum; bool flag; scanf("%d", &nCases); while (nCases--) { flag = 0; root = (Trie *)malloc(sizeof(Trie)); for (int i = 0; i < maxn; i++) root->next[i] = NULL; scanf("%d", &nNum); for (int i = 0; i < nNum; i++) { scanf("%s", str); if (findTrie(str) == -1)//找到一个前缀就退出此for循环 flag = 1; if (flag) continue; createTrie(str); } if (flag) printf("NO\n");//找到相同前缀,不合题意 else printf("YES\n"); del(root);//别忘了释放内存空间 } return 0; } 如有侵犯版权,请告知删除。
hdu1671
最新推荐文章于 2018-07-23 11:26:36 发布