字典树--- TOJ 2935 Phone List

题意

给定输入的n个电话号码,判断有没有某个号码是另一个的前缀。

很明显的字典树的应用,在模板上稍微修改即可:

代码

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

#define MAX 10
struct Trie{
    Trie *next[MAX]; //分支数
    int v;//以当前字符串为前缀的个数
};
Trie *root;
int T,n,flag;
void InitRoot()
{//初始化root 节点,以及一些全局变量
    root=(Trie*)malloc(sizeof(Trie));
    flag=0;
    for(int i=0; i<MAX; i++)
    {
        root->next[i]=NULL;
    }
}
void createTrie(char *str)
{//建立树
    Trie *p=root, *q;
    for(int i=0; i<strlen(str); i++)
    {
        int id=str[i]-'0';
        if(p->next[id])
        {//之前存在了前缀
            p->next[id]->v++;//更新计数
            p=p->next[id];
        }
        else
        {
            q=(Trie*)malloc(sizeof(Trie));//新建节点
            q->v=1;
            for(int i=0; i<MAX; i++)
                q->next[i]=NULL;
            p->next[id]=q;
            p=q;
        }
    }
    p->v=-1;//叶子节点标志
}

int findTrie(char *str)
{//查找
    Trie *p=root;
    for(int i=0; i<strlen(str); i++)
    {
        int id =str[i]-'0';
        p=p->next[id];
        if(!p) return 0;// 到结尾
        if (p->v==-1) return -1;//
    }
    return -1;
}
void del(Trie *T)
{//删除树
    for(int i=0;i<MAX; i++)
    {
        if(T->next[i]) del(T->next[i]);
    }
    free(T);
}
int main()
{
    char str[11];
    scanf("%d",&T);
    while(T--)
    {
        InitRoot();
        scanf("%d",&n);
        for(int i=0;i<n; i++)
        {
            scanf("%s",str);
            if(findTrie(str)==-1)
            {//存在前缀
                 flag=1;
                 continue;
            }
            createTrie(str);//否则 对Trie树 加入新的节点
        }
        flag?printf("NO\n"):printf("YES\n");
        del(root);
    }
}

你可能感兴趣的:(TOJ)