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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章