1 条题解
-
0
问题分析:
- 需要从头部字符串重建霍夫曼编码
- 编码必须满足前缀码性质(无歧义解码)
- 编码按字典序对应0到Z-1的字符
关键点:
- 头部字符串包含所有字符编码的拼接
- 编码必须构成完整的N叉树
- 需要找到唯一合理的编码分配
解题步骤:
- 构建N叉前缀树:
- 按字典序分配编码
- 确保无前缀冲突
- 解析头部字符串:
- 贪心匹配最小编码
- 验证编码完整性
- 输出字符到编码的映射
# include <cstring> # include <vector> using namespace std; struct node { node *nxt[20]; int count; bool end; node() { memset(nxt,NULL,sizeof(nxt)); count=0; end=0; } }; int z,n,count,len,c; node buffer[100000]; node *head; char str[250]; int ans[21]; void clear(node *p) { memset(p->nxt,NULL,sizeof(p->nxt)); p->end=false; p->count=0; } bool solve(int s,int left,node *p) { if(count>z||p->end) return false; if(s==len&&left==0) return true; else if(left<=0) return false; p->count++; if(p->count==1) { p->end=true; if(solve(s,left-1,head)) { ans[z-left+1]=s; return true; } p->end=false; } if(s==len) { p->count--; return false; } if(p->count==1) count+=n-1; if(p->nxt[str[s]-48]==NULL) { p->nxt[str[s]-48]=&buffer[c++]; clear(p->nxt[str[s]-48]); } if(solve(s+1,left,p->nxt[str[s]-48])) return true; if(p->count==1) count-=n-1; p->count--; return false; } int main() { int test; scanf("%d",&test); while(test--) { c=1; count=1; head=&buffer[0]; clear(head); scanf("%d%d%s",&z,&n,str); len=strlen(str); solve(0,z,head); ans[0]=0; for(int i=0;i<z;i++) { printf("%d->",i); for(int j=ans[i];j<ans[i+1];j++) printf("%c",str[j]); printf("\n"); } } return 0; }
- 1
信息
- ID
- 262
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- (无)
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者