pta5-9 Huffman Codes (30分)

5-9 Huffman Codes   (30分)

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

方法一:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<stack>
 5 #include<set>
 6 #include<map>
 7 #include<queue>
 8 #include<algorithm>
 9 using namespace std;
10 struct node{
11     string dight;
12     int weight;
13     bool operator<(const node &a) const {//什么情况下优先输出后面那个
14         if(weight==a.weight){
15             /*if(dight.length()==a.dight.length()){
16                 return dight.compare(a.dight)>0;
17             }*/
18             return dight.length()<a.dight.length();
19         }
20         return weight>a.weight;
21     }
22 };
23 node h[100];
24 map<char,int> ha;
25 int main(){
26     //freopen("D:\\INPUT.txt","r",stdin);
27     int n;
28     scanf("%d",&n);
29     int i,num,sum;
30     char cha;
31     for(i=0;i<n;i++){
32         cin>>cha;
33         scanf("%d",&ha[cha]);
34     }
35     scanf("%d",&num);
36     while(num--){
37         sum=0;
38         priority_queue<node> q;
39         for(i=0;i<n;i++){
40             cin>>cha>>h[i].dight;
41             //scanf("%s",h[i].dight);
42             sum+=ha[cha];
43             h[i].weight=ha[cha];
44             q.push(h[i]);
45         }
46         /*while(!q.empty()){
47             cout<<q.top().weight<<" "<<q.top().dight<<endl;
48             q.pop();
49         }*/
50         //cout<<num<<" "<<sum<<endl;
51         node cur,next;
52         queue<node> qq;
53         bool can;
54         while(!q.empty()){
55             cur=q.top();
56             q.pop();
57             can=false;
58             while(!q.empty()){
59                 next=q.top();
60                 q.pop();
61                 if(cur.dight.length()==next.dight.length()){
62                    if(cur.dight.substr(0,cur.dight.length()-1)==next.dight.substr(0,next.dight.length()-1)&&cur.dight[cur.dight.length()-1]!=next.dight[next.dight.length()-1]){
63                         can=true;
64                         while(!qq.empty()){//还原
65                             q.push(qq.front());
66                             qq.pop();
67                         }
68                         break;
69                    }
70                    else{
71                         qq.push(next);
72                    }
73                 }
74                 else{
75                     break;
76                 }
77             }
78             if(can){//找到了
79                 cur.dight=cur.dight.substr(0,cur.dight.length()-1);
80                 cur.weight+=next.weight;
81                 if(q.empty()){
82                    break;
83                 }
84                 q.push(cur);
85             }
86             else{
87                 break;
88             }
89         }
90         if(can&&cur.weight==sum&&!cur.dight.length()){
91             printf("Yes\n");
92         }
93         else{
94             printf("No\n");
95         }
96     }
97     return 0;
98 }

方法二:

学习网址:http://blog.csdn.net/u013167299/article/details/42244257

1.哈夫曼树法构造的wpl最小。

2.任何01字符串都不是其他字符串的前缀。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<stack>
 5 #include<set>
 6 #include<map>
 7 #include<queue>
 8 #include<algorithm>
 9 using namespace std;
10 struct node{
11     string s;
12     int count;
13 };
14 node p[80];
15 map<char,int> ha;
16 priority_queue<int,vector<int>,greater<int> > q;//从小到大排
17 bool check(node *p,int n){
18     int i,j;
19     for(i=0;i<n;i++){
20         string temp=p[i].s.substr(0,p[i].s.length());
21         for(j=0;j<n;j++){
22             if(i==j){
23                 continue;
24             }
25             if(temp==p[j].s.substr(0,p[i].s.length())){//前缀检查
26                 break;
27             }
28         }
29         if(j<n){//不满足要求
30             return false;
31         }
32     }
33     return true;
34 }
35 int main(){
36     //freopen("D:\\INPUT.txt","r",stdin);
37     int n,i;
38     scanf("%d",&n);
39     char c;
40     int wpl=0;
41     for(i=0;i<n;i++){
42         cin>>c;
43         scanf("%d",&ha[c]);
44         q.push(ha[c]);
45     }
46     int cur,next;
47     while(!q.empty()){
48         cur=q.top();
49         q.pop();
50         if(q.empty()){//最后一次不用做加法
51             break;
52         }
53         cur+=q.top();
54         q.pop();
55         wpl+=cur;
56
57         //cout<<cur<<endl;
58
59         q.push(cur);
60     }
61     //cout<<wpl<<endl;
62     int num;
63     scanf("%d",&num);
64     while(num--){
65         int sum=0;
66         for(i=0;i<n;i++){
67             cin>>c;
68             p[i].count=ha[c];
69             cin>>p[i].s;
70             sum+=p[i].count*p[i].s.length();
71         }
72
73 //        cout<<sum<<endl;
74
75         if(sum==wpl&&check(p,n)){
76             printf("Yes\n");
77         }
78         else{
79             printf("No\n");
80         }
81     }
82     return 0;
83 }
时间: 2024-10-08 10:27:47

pta5-9 Huffman Codes (30分)的相关文章

04-树6. Huffman Codes (30)

04-树6. Huffman Codes (30) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 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

Pat 04-树6. Huffman Codes (30)

题目链接: Huffman codes 题意: 先给出N个节点的出现次数 再给出M种编码方式 判断每种编码方式是否能构成哈夫曼树 题解: 判断哈夫曼编码的条件有两个: 1  哈夫曼编码不唯一,但它的WPL(带权路径长度)一定唯一 2  短码不能是长码的前缀 首先可以使用STL优先队列 根据  WPL=所有非叶节点的权值之和   求出标准的WPL1 再根据WPL2=所有叶节点的高度*权值之和 再单独判断是否编码中构成前缀 两个条件都满足则输出Yes #include<iostream> #inc

05-树9 Huffman Codes (30 分)

05-树9 Huffman Codes (30 分) 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

pta08-图7 公路村村通 (30分)

08-图7 公路村村通   (30分) 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本. 输入格式: 输入数据包括城镇数目正整数N(≤1000)和候选道路数目M(≤3N):随后的M行对应M条道路,每行给出3个正整数,分别是该条道路直接连通的两个城镇的编号以及该道路改建的预算成本.为简单起见,城镇从1到N编号. 输出格式: 输出村村通需要的最低成本.如果输入数据不足以保证畅通,则输出−1,表示需要建设更多公路. 输入样例: 6

PTA Huffman Codes

题目重现 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

Huffman codes

Huffman codes  compress data very effectively: savings of 20% to 90% are typical, depending on the characteristics of the data being compressed. 功能: huffman 编码能有效的压缩数据. 如何解决: Huffman’s greedy algorithm uses a table giving how often each character occ

PTA 07-图5 Saving James Bond - Hard Version (30分)

07-图5 Saving James Bond - Hard Version   (30分) This time let us consider the situation in the movie "Live and Let Die" in which James Bond, the world's most famous spy, was captured by a group of drug dealers. He was sent to a small piece of lan

5-10 公路村村通 (30分)

5-10 公路村村通   (30分) 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本. 输入格式: 输入数据包括城镇数目正整数NN(\le 1000≤1000)和候选道路数目MM(\le 3N≤3N):随后的MM行对应MM条道路,每行给出3个正整数,分别是该条道路直接连通的两个城镇的编号以及该道路改建的预算成本.为简单起见,城镇从1到NN编号. 输出格式: 输出村村通需要的最低成本.如果输入数据不足以保证畅通,则输出-1?1,

04-3. Huffman Codes (PAT) - 哈弗曼编码问题

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 enco