Pat 04-树6. Huffman Codes (30)

题目链接:

Huffman codes

题意:

先给出N个节点的出现次数

再给出M种编码方式

判断每种编码方式是否能构成哈夫曼树

题解:

判断哈夫曼编码的条件有两个:

1  哈夫曼编码不唯一,但它的WPL(带权路径长度)一定唯一

2  短码不能是长码的前缀

首先可以使用STL优先队列 根据  WPL=所有非叶节点的权值之和   求出标准的WPL1

再根据WPL2=所有叶节点的高度*权值之和

再单独判断是否编码中构成前缀

两个条件都满足则输出Yes

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
struct node1{
    char ch;
    int num;
}aa[105];
struct node2{
    char ch;
    string str;
}bb[105];
int n;
int cmp(node2 a,node2 b){
    return a.str.size()<b.str.size();
}
int pos(char a)
{
    for(int i=1;i<=n;i++)
        if(aa[i].ch==a)
            return i;
}
int judge(){                  //判断是否有前缀
    sort(bb+1,bb+1+n,cmp);
    for(int i=1;i<=n;i++){
        string t=bb[i].str;
        for(int j=i+1;j<=n;j++)
            if(bb[j].str.substr(0,t.size())==t)
                return 1;
    }
    return 0;
}
int main(){
    int m,ans1=0,ans2;
    scanf("%d",&n);
    priority_queue< int,vector<int>,greater<int> >q;
    for(int i=1;i<=n;i++)
    {
        cin>>aa[i].ch>>aa[i].num;
        q.push(aa[i].num);
    }
    int a,b;
    while(!q.empty()){
        a=q.top();
        q.pop();
        if(!q.empty()){    //最后队列中只会剩下一个根节点
            b=q.top();
            q.pop();
            q.push(a+b);
        }
        ans1+=a+b;
    }
    ans1=ans1-a-b;      //  WPL=所有非叶节点的权值之和
    scanf("%d",&m);
    while(m--){
        ans2=0;
        for(int i=1;i<=n;i++){
            cin>>bb[i].ch>>bb[i].str;
            ans2+=aa[pos(bb[i].ch)].num*bb[i].str.size(); //WPL2=所有叶节点的高度*权值之和
        }
        if(ans2!=ans1)
            cout<<"No"<<endl;
        else if(judge())
            cout<<"No"<<endl;
        else
            cout<<"Yes"<<endl;
    }
    return 0;
}
时间: 2024-11-18 01:08:39

Pat 04-树6. 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

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 o

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

PAT 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 enc

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

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

PAT甲题题解-1057. Stack (30)-树状数组

不懂树状数组的童鞋,正好可以通过这道题学习一下树状数组~~百度有很多教程的,我就不赘述了 题意:有三种操作,分别是1.Push key:将key压入stack2.Pop:将栈顶元素取出栈3.PeekMedian:返回stack中第(n+1)/2个小的数 建立一个栈来模拟push和pop,另外还需要树状数组,来统计栈中<=某个数的总个数不了解树状数组的建议学习一下,很有用的.树状数组为c,有个虚拟的a数组,a[i]表示i出现的次数sum(i)就是统计a[1]~a[i]的和,即1~i出现的次数当我要

数据结构学习笔记04树(堆 哈夫曼树 并查集)

一.堆(heap) 优先队列(Priority Queue):特殊的“队列”,取出元素的顺序是依照元素的优先权(关键字)大小,而不是元素进入队列的先后顺序. 数组 : 插入 — 元素总是插入尾部 ~ O ( 1 ) 删除 — 查找最大(或最小)关键字 ~ O ( n ) 从数组中删去需要移动元素 ~ O( n ) 链表: 插入 — 元素总是插入链表的头部 ~ O ( 1 ) 删除 — 查找最大(或最小)关键字 ~ O ( n ) 删去结点 ~ O( 1 ) 有序数组: 插入 — 找到合适的位置