ZJM 與生日禮物(字典樹)

問題描述

ZJM 收到了 Q老師 送來的生日禮物,但是被 Q老師 加密了。只有 ZJM 能夠回答對 Q老師 的問題,Q老師 纔會把密碼告訴 ZJM。

Q老師 給了 ZJM 一些僅有 01 組成的二進制編碼串, 他問 ZJM:是否存在一個串是另一個串的前綴.

Input

多組數據。每組數據中包含多個僅有01組成的字符串,以一個9作爲該組數據結束的標誌。

Output

對於第 k 組數據(從1開始標號),如果不存在一個字符串使另一個的前綴,輸出"Set k is immediately decodable",否則輸出"Set k is not immediately decodable"。
每組數據的輸出單獨一行

Sample input

01
10
0010
0000
9
01
10
010
0000
9

Sample output

Set 1 is immediately decodable
Set 2 is not immediately decodable

解題思路

這是一道基本的字典樹題目,我們判斷是否有前綴可以在插入的時候直接判斷,假設當前字符串是S,有兩種情況。

  1. 之前插入串是否是S的前綴
  2. S是否是之前插入串的前綴

對於第一種情況,我們只需要在插入S的過程中,判斷路徑上是否有結束的位置,如果有,則之前插入的串有S的前綴,否則沒有。

對於第二種情況,在S插入到最後一個位置的時候,判斷最後一個字母是否已經存在,如果存在,那麼S就是其他串的前綴,否則沒有。

完整代碼

//#pragma GCC optimize(2)
//#pragma G++ optimize(2)
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <climits>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;

struct Trie{
    static const int NodeNum=1010,charset=2;
    int tot,root,child[NodeNum][charset],flag[NodeNum];
    Trie(){
        memset(child,-1,sizeof(child));
        root=tot=0;
    }
    void clear(){
        memset(child,-1,sizeof(child));
        root=tot=0;
    }
    bool insert(char *str){
        int now=root,len=strlen(str);
        for (int i=0; i<len; i++){
            int x=str[i]-'0';
            if(child[now][x]==-1){
                child[now][x]=++tot;
                flag[now]=0;
            }
            else if(i==len-1 || flag[child[now][x]]) return true;
            now=child[now][x];
        }
        flag[now]=1;
        return false;
    }
};
const int maxn=100000+10;
char str[maxn];
int getint(){
    int x=0,s=1; char ch=' ';
    while(ch<'0' || ch>'9'){ ch=getchar(); if(ch=='-') s=-1;}
    while(ch>='0' && ch<='9'){ x=x*10+ch-'0'; ch=getchar();}
    return x*s;
}
int main(){
    //ios::sync_with_stdio(false);
    //cin.tie(0);
    int cnt=0;
    bool f=false;
    Trie trieTree;
    while(scanf("%s",str)!=EOF){
        if(str[0]=='9'){
            cnt++;
            printf("Set %d is ",cnt);
            if(f) printf("not ");
            printf("immediately decodable\n");
            f=false; trieTree.clear();
        }
        else f=trieTree.insert(str);
    }

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