ZJM与生日礼物
一、题目
ZJM 收到了 Q老师 送来的生日礼物,但是被 Q老师 加密了。只有 ZJM 能够回答对 Q老师 的问题,Q老师 才会把密码告诉 ZJM。
Q老师 给了 ZJM 一些仅有 01 组成的二进制编码串, 他问 ZJM:是否存在一个串是另一个串的前缀.
二、输入
多组数据。每组数据中包含多个仅有01组成的字符串,以一个9作为该组数据结束的标志。
三、输出
对于第 k 组数据(从1开始标号),如果不存在一个字符串使另一个的前缀,输出"Set k is immediately decodable",否则输出"Set k is not immediately decodable"。
每组数据的输出单独一行
四、样例输入输出
Input
01
10
0010
0000
9
01
10
010
0000
9
Output
Set 1 is immediately decodable
Set 2 is not immediately decodable
五、解题思路
字典树例题。(字典树样例:
字典树实现插入字符串,并标记字符串末尾节点。
本题只需要修改字典树的插入函数,在插入一个字符串s时,如果i==len-1&&child[now][x]!=-1,则说明s是之前某个字符串的前缀,在s插入树中的这个过程中,字典树中的节点并没有增多;而如果flag[child[now][x]]==1,则说明之前的某个字符串时s得前缀,在s插入树的过程中,经过了某个之前字符串的结束。
六、样例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | #include<stdio.h> #include<iostream> #include<string.h> #include<string> using namespace std; char str[1010]; struct trie { static const int N = 1010, charset = 10; int tot; int root; int child[N][charset]; int flag[N]; trie() { memset(child,-1,sizeof child); root = tot = 0; } int insert(char *str) { int now = root; int jud = 0; int 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]]) { jud = 1; } now = child[now][x]; } flag[now] = 1; return jud; } void clear() { memset(child,-1,sizeof child); root = tot = 0; } }; int main() { trie t; int ans = 0; int cnt = 0; while(scanf("%s",str) != EOF) { ans = max(ans, t.insert(str)); if(str[0]-'0' == 9) { cnt++; if(ans == 0) { cout<<"Set "<<cnt<<" is immediately decodable"<<endl; } else { cout<<"Set "<<cnt<<" is not immediately decodable"<<endl; } ans = 0; t.clear(); } } return 0; } |