hdu 1671 Phone List && POJ 3630 Phone List(静态申请空间)

题目链接:

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;
}


你可能感兴趣的:(字典树)