In 1953, David A. Huffman published his paper "A Method for the Construction of Minimum-Redundancy Codes", and hence printed his name in the history of computer science. As a professor who gives the final exam problem on Huffman codes, I am encountering a big problem: the Huffman codes are NOT unique. For example, given a string "aaaxuaxz", we can observe that the frequencies of the characters 'a', 'x', 'u' and 'z' are 4, 2, 1 and 1, respectively. We may either encode the symbols as {'a'=0, 'x'=10, 'u'=110, 'z'=111}, or in another way as {'a'=1, 'x'=01, 'u'=001, 'z'=000}, both compress the string into 14 bits. Another set of code can be given as {'a'=0, 'x'=11, 'u'=100, 'z'=101}, but {'a'=0, 'x'=01, 'u'=011, 'z'=001} is NOT correct since "aaaxuaxz" and "aazuaxax" can both be decoded from the code 00001011001001. The students are submitting all kinds of codes, and I need a computer program to help me determine which ones are correct and which ones are not.

Input Specification:

Each input file contains one test case. For each case, the first line gives an integer N (2≤N≤63), then followed by a line that contains all the N distinct characters and their frequencies in the following format:

c[1] f[1] c[2] f[2] ... c[N] f[N]

where c[i] is a character chosen from {'0' - '9', 'a' - 'z', 'A' - 'Z', '_'}, and f[i] is the frequency of c[i] and is an integer no more than 1000. The next line gives a positive integer M (≤1000), then followed by M student submissions. Each student submission consists of N lines, each in the format:

c[i] code[i]

where c[i] is the i-th character and code[i] is an non-empty string of no more than 63 '0's and '1's.

Output Specification:

For each test case, print in each line either "Yes" if the student's submission is correct, or "No" if not.

Note: The optimal solution is not necessarily generated by Huffman algorithm. Any prefix code with code length being optimal is considered correct.

Sample Input:

7
A 1 B 1 C 1 D 3 E 3 F 6 G 6
4
A 00000
B 00001
C 0001
D 001
E 01
F 10
G 11
A 01010
B 01011
C 0100
D 011
E 10
F 11
G 00
A 000
B 001
C 010
D 011
E 100
F 101
G 110
A 00000
B 00001
C 0001
D 001
E 00
F 10
G 11

Sample Output:

Yes
Yes
No
No
我的答案
 #include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h> #define MAXN 64
#define Yes 1
#define No 0 typedef struct TreeNode *HuffmanTree;
struct TreeNode {
int Weight;
HuffmanTree Left, Right;
}; /* MinHeap function */
#define MinData -1
typedef struct HeapStruct *MinHeap;
struct HeapStruct{
HuffmanTree Data;
int Size;
int Capacity;
}; #define QueueSize 100
struct QNode {
HuffmanTree Data[QueueSize];
int rear;
int front;
};
typedef struct QNode *Queue; MinHeap CreateMinHeap(int MaxSize);
int MinHeapIsFull(MinHeap H);
void MinHeapInsert(MinHeap H, HuffmanTree item);
int IsEmpty(MinHeap H);
HuffmanTree DeleteMin(MinHeap H);
void PrecDown(MinHeap H, int p);
void BuildMinHeap(MinHeap H);
void PrintMinHeap(MinHeap H);
HuffmanTree Huffman(MinHeap H);
MinHeap ReadData(int num, char *ch, int *cf, MinHeap H); void AddQ(Queue PtrQ, HuffmanTree item);
HuffmanTree DeleteQ(Queue PtrQ);
int IsEmptyQ(Queue PtrQ);
void LevelOrderTraversal(HuffmanTree HT); MinHeap CreateMinHeap(int MaxSize)
{
MinHeap H = (MinHeap)malloc(sizeof(struct HeapStruct));
H->Data = (HuffmanTree)malloc(sizeof(struct TreeNode)*(MaxSize+));
H->Size = ;
H->Capacity = MaxSize;
H->Data[].Weight = MinData; //哨兵
return H;
} int MinHeapIsFull(MinHeap H)
{
return (H->Size == H->Capacity);
} void MinHeapInsert(MinHeap H, HuffmanTree item)
{
int i;
if(MinHeapIsFull(H)) {
printf("Heap full");
return;
}
i = ++H->Size;
for(;H->Data[i/].Weight>item->Weight;i=i/) {
H->Data[i].Weight = H->Data[i/].Weight;
H->Data[i].Left = H->Data[i/].Left;
H->Data[i].Right = H->Data[i/].Right;
}
H->Data[i] = *item;
// free(item);
} int IsEmpty(MinHeap H)
{
return (H->Size == );
} HuffmanTree DeleteMin(MinHeap H)
{
int Parent, Child;
HuffmanTree MinItem, temp; MinItem = (HuffmanTree)malloc(sizeof(struct TreeNode));
temp = (HuffmanTree)malloc(sizeof(struct TreeNode)); if(IsEmpty(H)) {
printf("MinHeap Empty");
return NULL;
} *MinItem = H->Data[]; //保存最小的元素
*temp = H->Data[H->Size--]; //从最后一个元素插到顶点来比较
// printf("Size:%d\n", H->Size);
for(Parent=;Parent*<=H->Size;Parent=Child) { //有没有左儿子
Child = Parent*; //有的话比较左儿子
if((Child!=H->Size)&&(H->Data[Child].Weight>H->Data[Child+].Weight)) //比较左右儿子那个小
Child++;
if(temp->Weight <= H->Data[Child].Weight) break;
else {
H->Data[Parent].Weight = H->Data[Child].Weight;
H->Data[Parent].Left = H->Data[Child].Left;
H->Data[Parent].Right = H->Data[Child].Right;
}
}
H->Data[Parent] = *temp;
// free(temp);
return MinItem;
} void PrecDown(MinHeap H, int p)
{
int Parent, Child;
HuffmanTree temp; temp = (HuffmanTree)malloc(sizeof(struct TreeNode)); *temp = H->Data[p]; /* 取出根结点存放的值 */
for(Parent=p;Parent*<=H->Size;Parent=Child) { //有没有左儿子
Child = Parent*; //有的话比较左儿子
if((Child!=H->Size)&&(H->Data[Child].Weight>H->Data[Child+].Weight)) //比较左右儿子那个小
Child++;
if(temp->Weight <= H->Data[Child].Weight) break;
else
H->Data[Parent].Weight = H->Data[Child].Weight;
}
H->Data[Parent] = *temp;
} void BuildMinHeap(MinHeap H)
{
int i;
/* 从最后一个结点的父结点开始,到根结点1 */
for(i=H->Size/;i>;i--)
PrecDown(H, i);
} void PrintMinHeap(MinHeap H)
{
int i;
// printf("MinHeap: ");
for(i=;i<=H->Size;i++) {
printf(" %d", H->Data[i].Weight);
}
printf("\n");
} HuffmanTree Huffman(MinHeap H)
{
/* 假设H->Size个权值已经存在H->Elements[]->Weight里 */
int i;
HuffmanTree T;
BuildMinHeap(H); /* 将H->Elemnts[]按权值调整为最小堆 */
// PrintMinHeap(H);
for(i=;i<H->Size;) {
T = (HuffmanTree)malloc(sizeof(struct TreeNode)); /* 建立新结点 */
T->Left = DeleteMin(H); /* 从最小堆中删除一个结点,作为新T的左子结点 */
T->Right = DeleteMin(H); /* 从最小堆中删除一个结点,作为新T的右子结点 */
T->Weight = T->Left->Weight+T->Right->Weight; /* 计算新权值 */
MinHeapInsert(H, T);
// PrintMinHeap(H);
// printf("Huffman:");
// LevelOrderTraversal(T);
// printf("\n");
}
T = DeleteMin(H);
return T;
} void PrintHuffman(HuffmanTree HT)
{
if(HT) {
PrintHuffman(HT->Left);
PrintHuffman(HT->Right);
printf("%d ", HT->Weight);
}
} MinHeap ReadData(int num, char *ch, int *cf, MinHeap H)
{
int i;
for(i=;i<num;i++) {
if(i==num-)
scanf("%c %d", &ch[i], &cf[i]);
else
scanf("%c %d ", &ch[i], &cf[i]);
HuffmanTree T = (HuffmanTree)malloc(sizeof(struct TreeNode));
T->Weight = cf[i];
MinHeapInsert(H, T);
}
return H;
} int WPL(HuffmanTree T, int Depth)
{
// printf("T->Weight = %d, T->Left = %p, T->Right =%p\n",
// T->Weight, T->Left, T->Right);
int rw=, lw=;
if(!T->Left && !T->Right)
return (Depth*(T->Weight));
else {
if(T->Left) lw = WPL(T->Left, Depth+);
if(T->Right) rw = WPL(T->Right, Depth+);
return lw+rw;
}
} HuffmanTree CreateHuffmanTree()
{
HuffmanTree T = (HuffmanTree)malloc(sizeof(struct TreeNode));
T->Weight = ;
T->Left = T->Right = NULL;
return T;
} void DeleteHuffmanTree(HuffmanTree T)
{
if(T) {
DeleteHuffmanTree(T->Left);
DeleteHuffmanTree(T->Right);
free(T);
}
} int Judge(int N, int CodeLen, char *ch, int *cf)
{
char s1[MAXN], s2[MAXN];
int i, j, weight, flag = Yes;
HuffmanTree T = CreateHuffmanTree();
HuffmanTree pt = NULL;
for(i=;i<N;i++) {
scanf("%s %s\n", s1, s2);
if(strlen(s2) > N) { flag = No; break; }
for(j=;s1[]!=ch[j];j++)
if(j==N) { flag = No; break; }
weight = cf[j];
pt = T;
for(j=;j<strlen(s2);j++) {
if(s2[j] == '') { //开始创建树
if(!pt->Left) pt->Left = CreateHuffmanTree(); //没有就创建
else if(pt->Left->Weight != ) {
// printf("Exit from pt->Left->Weight == 1\n");
flag = No; //是否路过叶子
}
pt = pt->Left;
} else if(s2[j] == '') {
if(!pt->Right) pt->Right = CreateHuffmanTree();
else if(pt->Right->Weight != ) {
// printf("Exit from pt->Right->Weight == 1\n");
flag = No;
}
pt = pt->Right;
} else { //应该不会发生
// printf("Exit from not happen\n");
flag = No;
}
}
pt->Weight = weight; //叶子标记
weight = ; //清空weight
if(pt->Left || pt->Right) {
// printf("Exit from pt->Left || pt->Right\n");
flag = No; //不是叶子也错
}
}
if(flag != No && CodeLen == WPL(T, )) {
return Yes;
} else {
// printf("Exit from CodeLen != WPL(T, 0) %d\n", WPL(T, 0));
if(T) DeleteHuffmanTree(T);
return No;
}
} int main()
{
int N, CodeLen, n, i; //huffman的叶子结点个数,WPL最优值
MinHeap H; //最小堆
char *ch; //输入的字符组
int *cf;
HuffmanTree T; //HuffmanTree
scanf("%d\n", &N);
H = CreateMinHeap(N);
ch = (char *)malloc(sizeof(char)*N);
cf = (int *)malloc(sizeof(int)*N);
H = ReadData(N, ch, cf, H);
T = Huffman(H);
CodeLen = WPL(T, );
scanf("%d\n", &n);
for(i=;i<n;i++) {
if(Judge(N, CodeLen, ch, cf))
printf("Yes\n");
else
printf("No\n");
}
return ;
}

05-树9 Huffman Codes(30 分)的更多相关文章

  1. pta5-9 Huffman Codes (30分)

    5-9 Huffman Codes   (30分) In 1953, David A. Huffman published his paper "A Method for the Const ...

  2. PTA 05-树9 Huffman Codes (30分)

    题目地址 https://pta.patest.cn/pta/test/16/exam/4/question/671 5-9 Huffman Codes   (30分) In 1953, David ...

  3. 05-树9 Huffman Codes (30 分)

    In 1953, David A. Huffman published his paper "A Method for the Construction of Minimum-Redunda ...

  4. pat树之专题(30分)

    (好好复习是王道) 1115. Counting Nodes in a BST (30) 分析:简单题——将bst树构造出来,然后给每个节点打上高度.最后求出树的高度.然后count树高的节点数加上树 ...

  5. 05-树9 Huffman Codes (30 分)

    In 1953, David A. Huffman published his paper "A Method for the Construction of Minimum-Redunda ...

  6. 05-树9 Huffman Codes (30 分)

    In 1953, David A. Huffman published his paper "A Method for the Construction of Minimum-Redunda ...

  7. PAT 甲级1057 Stack (30 分)(不会,树状数组+二分)*****

    1057 Stack (30 分)   Stack is one of the most fundamental data structures, which is based on the prin ...

  8. Huffman codes

    05-树9 Huffman Codes(30 分) In 1953, David A. Huffman published his paper "A Method for the Const ...

  9. PAT 甲级 1053 Path of Equal Weight (30 分)(dfs,vector内元素排序,有一小坑点)

    1053 Path of Equal Weight (30 分)   Given a non-empty tree with root R, and with weight W​i​​ assigne ...

随机推荐

  1. 英语单词forwarding

    forwarding 来源——xshell的远程连接 [c:\~]$ Connecting to ... Connection established. To escape to local shel ...

  2. paper 154:姿态估计(Hand Pose Estimation)相关总结

    Awesome Works  !!!! Table of Contents Conference Papers 2017 ICCV 2017 CVPR 2017 Others 2016 ECCV 20 ...

  3. LOJ 3058 「HNOI2019」白兔之舞——单位根反演+MTT

    题目:https://loj.ac/problem/3058 先考虑 n=1 怎么做.令 a 表示输入的 w[1][1] . \( ans_t = \sum\limits_{i=0}^{L}C_{L} ...

  4. Fraction Comparision

    题目链接 题意:输入x,a,y,b求x/a和y/b的大小,范围long long int 思路:因为不想用精度,嫌麻烦,所以用了个巧方法.先求x/a和y/b整形的大小,如果相等,再求(x%a)*b和( ...

  5. fine report 连接mysql (mac)

    把 /Applications/FineReport/webapps/webroot/WEB-INF/lib 下mysql-connector-java-5.1.39-bin.jar 删掉 在 htt ...

  6. 解决修改 Linux 下的 PHP 环境变量不生效的方法

    这个问题出现服务器有多个 PHP 版本,php -v和phpinfo()显示两个不同的版本 最近真的,都给朋友解决问题了... phpinfo查看的 php 版本是 7.2.6,到 bash 去使用p ...

  7. APIO2010 特别行动队 & 斜率优化DP算法笔记

    做完此题之后 自己应该算是真正理解了斜率优化DP 根据状态转移方程$f[i]=max(f[j]+ax^2+bx+c),x=sum[i]-sum[j]$ 可以变形为 $f[i]=max((a*sum[j ...

  8. English-such as, for example, include and contain

    such as 后接动词,通常用动名词,有时也可用动词原形 for example 后接动词,用动名词 include vt. 包含,包括 后接动词,用动名词 英英: If one thing inc ...

  9. SPRING CLOUD微服务DEMO-下篇

    目录 1 Hystix 1.1 简介 1.2 配置并测试 2. Feign 2.1 简介 2.2 使用Feign 2.3 负载均衡 2.4 Hystrix支持 2.5.请求压缩 3. Zuul网关 3 ...

  10. datastudion 资源导入python包,编写模块

    学习文档,不懂再问. https://help.aliyun.com/document_detail/74423.html?spm=a2c4g.11186623.6.688.72635debHqgkV ...