Light OJ 1129 Trie樹 動態建樹

做了一道POJ 2001,對TRIE樹的思想差不多理解了。其實TRIE樹的思想很簡單,就是建樹,每個節點都有26個子節點(如果是數字的話,那就是10個),然後每個單詞從頭到尾按照樹的深度找下去,最後所有這些單詞就掛在TRIE樹上啦。


對於TRIE樹的操作有:插入、刪除、搜索等等。每個操作都很重要,刪除如果沒有的話在多組數據中就基本上要MLE了,這道題就是這樣,一開始我沒有做刪除操作,MLE了5次。


題意:給你n個數(n <= 10000),問這些數中有沒有某個數是另一個數的前綴,比如111和1110。有就輸出NO,否則就輸出YES。

思路很簡單:因爲是前綴,因此可以維護TRIE樹,維護好之後,再去從TRIE樹上找每個數字,如果某個數字已經找到它應該到的結點之後,還能再往下找到其他的數,那就說明滿足題目說的條件了,退出判斷即可。這種字符串匹配的題目,一開始可能會想到KMP,但是想想如果每個字符都和其他字符去做一遍KMP,那得O(n^2)的複雜度,肯定是要超時的。


順便吐一個自己的槽,指針沒學好真傷不起,malloc和free都用得不溜。敲打


Code:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int n;
char a[10001][11];
struct node
{
    struct node *next[10];
};

void insert(node *root, const char *tar)
{
    if(root == NULL || *tar == '\0')
        return;
    int id;
    node *p = root;
    while(*tar)
    {
        id = *tar - '0';
        if(p -> next[id] == NULL)
        {
            node *temp = (node *)malloc(sizeof(node));
            for(int i = 0; i < 10; i ++)
                temp -> next[i] = NULL;
            p -> next[id] = temp;
        }
        p = p -> next[id];
        tar ++;
    }
}

bool search(node *root, const char *tar)
{
    int id;
    node *p = root;
    while(*tar && p != NULL)
    {
        id = *tar - '0';
        p = p -> next[id];
        tar ++;
    }
    for(int i = 0; i < 10; i ++)
        if(p -> next[i] != NULL)
            return true;
    return false;
}

void delnode(node *tar)
{
    int i;
    for(int i = 0; i < 10; i ++)
    {
        if(tar -> next[i] != NULL)
            delnode(tar -> next[i]);
    }
    free(tar);
}

int main()
{
    int cse, t = 1;
    scanf("%d", &cse);
    while(cse --)
    {
        node *root = (node *)malloc(sizeof(node));
        for(int i = 0; i < 10; i ++)
            root -> next[i] = NULL;
        scanf("%d", &n);
        for(int i = 0; i < n; i ++)
        {
            scanf("%s", a[i]);
            insert(root, a[i]);
        }
        bool yes = true;
        for(int i = 0; i < n; i ++)
            if(search(root, a[i]))
            {
                yes = false;
                break;
            }
        if(yes)
            printf("Case %d: YES\n", t ++);
        else
            printf("Case %d: NO\n", t ++);
        delnode(root);
    }

}





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