之前所写代码在 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\n");
break;
}
}
if (i == n) {
printf("YES\n");
}
}
return 0;
}