HDU1671 - Phone List(Trie树)

题目大意

给定一些电话号码,判断是否有电话号码是其他电话号码的前缀

题解

裸Trie树嘛~~~~只需要一个插入过程即可,假设X是Y的前缀,在插入的过程中有两种情况,X在Y之前插入,那么在插入Y的时候经过了X的尾结点,插入的过程中判断下即可,还有一种情况就是X在Y之后插入,那么插入X的时候肯定不需要插入新结点~~~也记录一下即可~~~~~被坑了好多次,先是没有考虑第二种情况,改了之后RE,然后脑残的发现把数字字符转换为数字的时候是-‘a’…改完就AC了。。。

代码:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxnode=111111;
const int sigma_size=11;
bool flag;
int ans;
struct Trie
{
    int ch[maxnode][sigma_size];
    int  val[maxnode];
    int sz;
    void clear(){sz=1;memset(val,0,sizeof(val));memset(ch[0],0,sizeof(ch[0]));}
    int idx(char c){return c-'0';}
    void insert(char *s)
    {
        int u=0,n=strlen(s),ans=0;
        for(int i=0;i<n;i++)
        {
            int c=idx(s[i]);
            if(!ch[u][c])
            {
                memset(ch[sz],0,sizeof(ch[sz]));
                ch[u][c]=sz++;
                ans++;
            }
            else
                if(val[ch[u][c]])
                    flag=true;
            u=ch[u][c];
        }
        if(!ans) flag=true;
        val[u]++;
    }
};
Trie trie;
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        trie.clear();
        char num[15];
        int n;
        flag=false;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%s",num);
            if(flag) continue;
            trie.insert(num);
        }
        if(flag)
            printf("NO\n");
        else
            printf("YES\n");
    }

    return 0;
}

posted on 2013-09-13 09:56  仗剑奔走天涯  阅读(190)  评论(0编辑  收藏  举报

导航