题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1671
http://poj.org/problem?id=3630
解题思路:
本来不准备写这封博客的,但是今天一学弟对我说,动态申请空间的这份代码在POJ上交会超时,于是试了试,果然超时了。然后就学会了新的处理字典树的方法,静态申请空间,不需要频繁的调用new,所以效率会更高。。。
AC代码(动态申请空间,hdu能过,poj超时):
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
char str[10005][15];
struct node
{
int cnt;
struct node *next[10];
node()
{
cnt = 0;
memset(next,0,sizeof(next));
}
};
node *root = NULL;
void buildtrie(char *s)
{
node *p = root;
node *tmp = NULL;
int i,l = strlen(s);
for(i = 0; i < l; i++)
{
if(p->next[s[i]-'0'] == NULL)
{
tmp = new node;
p->next[s[i]-'0'] = tmp;
}
p = p->next[s[i]-'0'];
p->cnt++;
}
}
bool findtrie(char *s)
{
node *p = root;
int i,l = strlen(s);
for(i = 0; i < l; i++)
p = p->next[s[i]-'0'];
if(p->cnt != 1)
return true;
return false;
}
void del(node *root)
{
for(int i = 0; i < 10; i++)
if(root->next[i])
del(root->next[i]);
delete(root);
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
root = new node;
int n;
scanf("%d",&n);
for(int i = 1; i <= n; i++){
scanf("%s",str[i]);
buildtrie(str[i]);
}
int flag = 1;
for(int i = 1; i <= n; i++){
if(findtrie(str[i])){
flag = 0;
break;
}
}
if(flag)
printf("YES\n");
else
printf("NO\n");
del(root);
}
return 0;
}
AC代码(静态申请空间):
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
char str[10005][15];
int cnt_node;
struct node
{
int cnt;
struct node *next[10];
void init()
{
cnt = 0;
memset(next,0,sizeof(next));
}
}Heap[100005];
inline node* new_node(){
Heap[cnt_node].init();
return &Heap[cnt_node++];
}
node *root = NULL;
void buildtrie(char *s)
{
node *p = root;
node *tmp = NULL;
int i,l = strlen(s);
for(i = 0; i < l; i++)
{
if(p->next[s[i]-'0'] == NULL)
{
tmp = new_node();
p->next[s[i]-'0'] = tmp;
}
p = p->next[s[i]-'0'];
p->cnt++;
}
}
bool findtrie(char *s)
{
node *p = root;
int i,l = strlen(s);
for(i = 0; i < l; i++)
p = p->next[s[i]-'0'];
if(p->cnt != 1)
return true;
return false;
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
cnt_node = 0;
root = new_node();
int n;
scanf("%d",&n);
for(int i = 1; i <= n; i++){
scanf("%s",str[i]);
buildtrie(str[i]);
}
int flag = 1;
for(int i = 1; i <= n; i++){
if(findtrie(str[i])){
flag = 0;
break;
}
}
if(flag)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}