hdu 1671 Phone List 字典樹(靜態版)



HDU1671

------明天就要放清明節4天長假了,今天居然下起了小雨,真是涼颼颼啊。啊......,估計四天假又要虛度了,不行我至少要學點東西奮鬥。。


          《Phone List》 題目很簡單,字典樹模板稍作修改就可實現。我做的用字典樹方法,但是我要事先把所有的電話號用字典序從小到大排下序,但是後來發現


排完序的話直接比較相鄰兩個其中一個電話是否是另一個電話號的前綴就可,字典樹多此一舉了額。


           題意:給你幾個電話號,如果某個電話號是另一個電話號的前綴的話,那麼這個另一個電話就永遠不能被打過去,輸出NO,否則輸出YES。。


          思路:把電話號先按字典序從小到大排下序,依次的往字典樹中插入手機號。單詞(手機號)的尾節點保存着1代表字典樹中已有該手機號。然後在插入手機號的過程中如果發現某個節點保存1,就輸出NO。

       

           字典樹的意思就是先給一個根節點,然後順着這條根節點往下連接兒子節點的那條邊作爲單詞的一個字母,如果存在這個字母就下去找那個兒子節點,然後同理找下一個字母。不存在這個字母的話,根節點就再生一個兒子,然後繼續不斷地生..查找同理,字母不存在就說明沒這個單詞


本題代碼

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <iostream>
#include <algorithm>
#include <map>
using namespace std;
char s[10010][15];
int ch[80010][10];
int val[80010], tmp;
int cmpp(const void *a, const void *b)
{
    return strcmp((char*)a, (char*)b);
}

int insert(char *a)
{
    int rt = 0, x;
    for (int i = 0; a[i]; i++)
    {
        x = a[i] - '0';
        if (ch[rt][x] == 0)
        {
            if (val[rt] == 1)
            return 0;
            val[tmp] = 0;
            ch[rt][x] = tmp++;
        }
        rt = ch[rt][x];
    }
    if (val[rt] == 1) return 0;
    val[rt] = 1;
    return 1;
}

int main()
{
    int t;
    scanf("%d", &t);
    while (t--)
    {
        int n;
        scanf("%d", &n);
        tmp = 1;
        val[0] = 0;
        memset(ch[0], 0, sizeof ch);
        for (int i = 0; i < n; i++)
        scanf("%s", s[i]);
        qsort(s, n, sizeof(s[0]), cmpp);
        int ans = 0;
        for (int i = 0; i < n; i++)
        {
            if (insert(s[i]) == 0)
            {
                ans = 1;break;
            }
        }
        if (ans) printf("NO\n");
        else printf("YES\n");
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章