之前所写代码在 poj 3630 题无法AC,现换另外一种实现方式,hdu、poj 皆可AC。
(poj无法AC原因:动态分配内存空间花费时间较多,导致超时)
一、题目:
若存在其中一个电话的符号串是另一个电话的前缀,则定义为: this list would not be consistent. 输出:NO
否则,输出:YES。
二、思考:
考虑两种情况:
(1)若每个符号串在建立串的过程中,
1)有其他串,作为该符号串子串,输出:NO (代码中:Ju2 = true)
2)该符号串作为其他串的子串,输出:NO (代码中 Ju1 = true )
(2)不满足(1),输出:YES
三、解法:
在字典树中加一个 bool 变量,用于判断当前节点是否作为一个电话符号串的结尾字符。
#include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> using namespace std; const int MAX = 10; int Trie_pos; struct Trie { bool Judge; Trie *next[MAX]; }; Trie Memory[100000]; Trie *Root; Trie* CreTrie_ptr() { Trie* p; p = &Memory[Trie_pos++]; p->Judge = false; memset(p->next, NULL, sizeof(p->next)); return p; } bool Cre_Judge_Trie(char *str) { bool Ju1 = true, Ju2 = false; int len = strlen(str); Trie *p = Root; for (int i = 0; i < len; ++i) { int pos = str[i] - '0'; if (!(p->next[pos])) { Ju1 = false; p->next[pos] = CreTrie_ptr(); } else { if (p->next[pos]->Judge) { Ju2 = true; break; } } p = p->next[pos]; } p->Judge = true; return (Ju1 || Ju2); } int main() { //freopen("input.txt", "r", stdin); int t; scanf("%d", &t); while (t--) { Trie_pos = 0; Root = CreTrie_ptr(); int n; scanf("%d", &n); char add_ch[10000][10]; for (int j = 0; j < n; j++) { scanf("%s", add_ch[j]); } int i; for (i = 0; i < n; i++) { if (Cre_Judge_Trie(add_ch[i])) { printf("NO "); break; } } if (i == n) { printf("YES "); } } return 0; }