POJ_3630_Phone List_Trie樹

題目大意是給定t組數據,每組中有n個數字構成的字符串電話號碼,要求對每一組數據判斷是否存在一個電話號碼爲另一個的前綴,如果有,則這一組數據不合要求,輸出”NO”,若是沒有,就是”YES”。

一眼就看出來這道題是一個裸的trie樹問題,需要利用trie樹這種結構判斷是否存在前綴即可。

用trie樹先記錄每個電話號碼,並將它們最末一位存下來,之後遍歷所有電話號碼的最末一位,如果某一個有子結點,就說明它所對應的電話號碼爲另一個的前綴。若均沒有,則不存在一個電話號碼爲另一個的前綴。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N=100009;
const int inf = 0x3f3f3f3f;
int n;
int tree[N][10],tot;
bool p[N];
int trie(char w[])
{
    int loc=0;//0號結點是虛擬的根結點
    for (int i=0;w[i];i++)//把號碼的每一位都在樹上走一遍
    {
        int x=tree[loc][w[i]-'0'];
        if (x==-1)//如果下一位數字的位置還未出現過,新建一個結點並編號
            tree[loc][w[i]-'0']=++tot;
        loc=tree[loc][w[i]-'0'];//繼續走下一位數字
    }
    return loc;//返回最末一位數字
}
int main()
{
    int c;
    for (scanf ("%d",&c);c--;)
    {
        memset (tree,-1,sizeof(tree));
        memset (p,false,sizeof(p));
        tot=0;
        scanf ("%d",&n);
        for (int i=1;i<=n;i++)
        {
            char s[21];
            scanf ("%s",s);
            p[trie(s)]=true;//將號碼最後一個數字編號記錄下
        }
        bool k=false;
        for (int i=1;i<=tot;i++)
        {
            if (p[i]==true)//查詢每個電話號碼的最後一位
            {
                for (int j=0;j<=9;j++)
                    if (tree[i][j]!=-1)//如果發現某個電話號碼的最後一位有子結點,則存在前綴
                    {
                        k=true;
                        break;
                    }
            }
        }
        if(k) 
            puts("NO");
        else
            puts("YES");
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章