您的位置:首页 > 其它

POJ 3630 - Phone List (Trie树)

2014-08-01 21:01 441 查看
题目:http://poj.org/problem?id=3630

题意:

t组数据,每组数据n行号码,若每个号码都不是其他任意号码的前缀,则YES

分析:

建立Trie树,判断新加入号码前缀是否已经为出现过号码(如:加入1234,已经出现过123),或该号码为已经出现号码的前缀(如:加入123,已经出现1234)

代码:

#include <stdio.h>
#include <iostream>
#include <string.h>
#include <string>
#include <math.h>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <map>

using namespace std;

#define MAX 1000+10
#define MIN -1e+10
#define INF 0x7f7f7f7f

int t, n, m;

struct Trie
{
int id; // 号码是否出现
Trie *child[10]; // 叶子指针
}root, tries[100000+10]; // 根节点,静态数组(动态超时)

int t_num; // 节点数

int insert(char str[]) // 插入号码str
{
Trie* x = &root;
int ok = 0; // 加入号码后,无新节点生成,则该号码为其他号码的前缀
for(int i = 0; str[i]; i++)
{
if(x->id) return 0;
if(!x->child[str[i]-'0'])
{
ok = 1; // 有新节点生成,则该号码不是其他号码的前缀
tries[t_num].id = 0;
memset(tries[t_num].child, 0, sizeof(tries[t_num].child)); // 新节点初始化
x->child[str[i]-'0'] = &tries[t_num++];
}
x = x->child[str[i]-'0'];
}
x->id = 1;
return ok;
}

int main()
{
int i, j, k;
//freopen("a.txt", "r", stdin);

scanf("%d", &t);
while(t--)
{
scanf("%d", &n);
cin.get();
char str[1000+10];
int ok = 1;
t_num = 0;
memset(root.child, 0, sizeof(root.child)); // 根节点初始化
for(i = 0; i<n; i++)
{
gets(str);
if(ok ) ok = insert(str);
}
if(ok)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: