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;

}

你可能感兴趣的:(list)