1 条题解
-
0
一、问题核心
本题的核心是判断给定的二进制编码集合是否立即可解码,即集合中没有一个编码是另一个编码的前缀。输入为一系列编码组,每个编码组由若干二进制编码组成,编码组之间用单独的数字 “9” 分隔,需要对每个编码组独立判断其是否立即可解码。
二、关键思路
(一)输入处理 从标准输入读取数据,按行处理。当读取到数字 “9” 时,表明一个编码组结束,开始对该编码组进行判断。 使用一个集合(如 codes_set)来存储当前编码组的编码,利用集合的特性自动去除重复编码。 (二)前缀判断 遍历编码集合中的每一个编码(设为 code1),对于每个 code1,再遍历集合中除 code1 之外的其他编码(设为 code2)。 判断 code1 是否是 code2 的前缀,或者 code2 是否是 code1 的前缀。判断前缀的方法可以通过字符串的切片操作来实现,例如,对于两个编码 code1 和 code2,若 code1 的长度小于 code2 的长度,且 code2 的前 len(code1) 个字符与 code1 相同,则 code1 是 code2 的前缀。 如果发现存在一个编码是另一个编码的前缀,则该编码组不是立即可解码的;若遍历完所有编码都没有发现前缀关系,则该编码组是立即可解码的。 (三)输出结果 对于每个编码组,记录其组号(从 1 开始)。 根据前缀判断的结果,输出相应的信息,格式为 “Set [组号] is [not] immediately decodable”,其中 “[not]” 根据实际情况决定是否输出。
三、示例代码(c++)
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N =5005; int tr[N][3],n,t; bool p[N]; char s[45]; int trie(char w[]) { int loc=0; for (int i=0;w[i];i++) { int x=tr[loc][w[i]-'0']; if (x==-1) tr[loc][w[i]-'0']=++t; loc=tr[loc][w[i]-'0']; } return loc; } int main() { n=1; t=0; memset (tr,-1,sizeof(tr)); memset (p,false,sizeof(p)); while (scanf ("%s",s)!=EOF) { if (s[0]=='9') { bool k=false; for (int i=1;i<=t;i++) { if (p[i]) if (tr[i][0]!=-1||tr[i][1]!=-1) { k=true; break; } } if (!k) printf("Set %d is immediately decodable\n",n); else printf("Set %d is not immediately decodable\n",n); n++; memset (tr,-1,sizeof(tr)); memset (p,false,sizeof(p)); t=0; } else p[trie(s)]=true; } return 0; }
- 1
信息
- ID
- 57
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者