您的位置:首页 > 其它

POJ 3630:Phone List(字典树入门)

2017-08-13 08:31 519 查看
题目链接:http://poj.org/problem?id=3630

题目意思:

如果拨打的电话号码的前缀是一个完整的电话号码,则这个电话就不能拨通,判断给出的电话列表是否全部能拨通。

这个题目只用再建立字典树的过程中做判断就行了,没必要建完之后再去查询,我们可以在节点设置count统计某个

节点所代表的单词当前称为别人前缀的次数。再用个bool变量记录当前节点所代表的一串字符是不是一个完整的电话

号码,当一个字符串是完整的电话号码,且被已经加入的串当作前缀两次,这列电话号码就不能全部拨通。

坑点:

1.不能是用动态链表,malloc动态分配内存提交会超时,这个题目得用静态链表。

2.静态链表数组开到一两万过不去,尽量开大点,我直接开10万过了。

AC代码:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

using namespace std;

const int maxn = 10;
char telNum[10002][14];
struct TrieNode
{
bool isCompleteTel;
int ccount;
struct TrieNode *son[maxn];
}node[100000];
int num;
TrieNode* createNode()
{
TrieNode *p = &node[num++];
for(int i = 0; i < maxn; i++)
{
p->son[i] = NULL;
}
return p;
}
///边插入Telphone边判断。不用建玩树后再去一个个判断。
bool insertTel(TrieNode *root,char tel[])
{
TrieNode *p;
p = root;
int i = 0;
char ch = tel[i];
while(ch != '\0')
{
if(p->son[ch-'0'] == NULL)
{

p->son[ch-'0'] = createNode();
p = p->son[ch-'0'];
p->isCompleteTel = false;
p->ccount = 1;
}
else
{
p->son[ch-'0']->ccount++;
p = p->son[ch-'0'];
if(p->ccount>1 && p->isCompleteTel==true) ///如果有一串完整电话号码已经到过这里了。就不能拨打成功。
return false;
}
ch = tel[++i];
}
p->isCompleteTel = true;
if(p->ccount>1 && p->isCompleteTel==true) ///曾经有电话号码的前缀到达过这个电话号码的结尾了,也不行。
return false;
return true;
}
int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
num = 0;
scanf("%d",&n);
bool OK = true;
TrieNode *root = createNode();
for(int i = 0; i < n; i++)
{
scanf("%s",telNum[i]);
if(OK)
{
OK = insertTel(root,telNum[i]);
}
}
if(OK)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: