哈夫曼编码 (30 分)

简介: 哈夫曼编码 (30 分)

给定一段文字,如果我们统计出字母出现的频率,是可以根据哈夫曼算法给出一套编码,使得用此编码压缩原文可以得到最短的编码总长。然而哈夫曼编码并不是唯一的。例如对字符串"aaaxuaxz",容易得到字母 'a'、'x'、'u'、'z' 的出现频率对应为 4、2、1、1。我们可以设计编码 {'a'=0, 'x'=10, 'u'=110, 'z'=111},也可以用另一套 {'a'=1, 'x'=01, 'u'=001, 'z'=000},还可以用 {'a'=0, 'x'=11, 'u'=100, 'z'=101},三套编码都可以把原文压缩到 14 个字节。但是 {'a'=0, 'x'=01, 'u'=011, 'z'=001} 就不是哈夫曼编码,因为用这套编码压缩得到 00001011001001 后,解码的结果不唯一,"aaaxuaxz" 和 "aazuaxax" 都可以对应解码的结果。本题就请你判断任一套编码是否哈夫曼编码。


输入格式:

首先第一行给出一个正整数 N(2≤N≤63),随后第二行给出 N 个不重复的字符及其出现频率,格式如下:

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


其中c[i]是集合{'0' - '9', 'a' - 'z', 'A' - 'Z', '_'}中的字符;f[i]c[i]的出现频率,为不超过 1000 的整数。再下一行给出一个正整数 M(≤1000),随后是 M 套待检的编码。每套编码占 N 行,格式为:

c[i] code[i]

其中c[i]是第i个字符;code[i]是不超过63个'0'和'1'的非空字符串


输出格式:

对每套待检编码,如果是正确的哈夫曼编码,就在一行中输出"Yes",否则输出"No"。

注意:最优编码并不一定通过哈夫曼算法得到。任何能压缩到最优长度的前缀编码都应被判为正确。


输入样例:

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


输出样例:

1. Yes
2. Yes
3. No
4. No


思路:要满足是哈夫曼编码得满足两个条件:

1:哈夫曼编码的带权路径和唯一

2:任意编码都不能是其他编码的前缀

#include<bits/stdc++.h>
using namespace std;
const int N = 70;
int cnt[N];
int main()
{
    priority_queue<int,vector<int>,greater<int>> q;
    int n,sum = 0;
    char op;
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>op>>cnt[i];
        q.push(cnt[i]);
    }
    while(q.size() > 1)
    {
        int a = q.top();
        q.pop();
        int b = q.top();
        q.pop();
        sum += a + b;
        q.push(a + b);
    }
    int T;
    cin>>T;
    while(T -- )
    {
        string s,f[N];
        int ans = 0;
        for(int i=0;i<n;i++)
        {
            cin>>op>>s;
            ans += s.size() * cnt[i];
            f[i] = s;
        }
        if(ans != sum) puts("No");
        else
        {
            int t = 0;
            for(int i=0;i<n;i++)
                for(int j=0;j<n;j++)
                    if(f[j].size() >= f[i].size() && i != j)
                        if(f[j].substr(0,f[i].size()) == f[i])
                            t = 1;
            if(t) puts("No");
            else puts("Yes");
        }
    }
    return 0;
}
目录
相关文章
|
资源调度 前端开发 JavaScript
开源项目:Linux系统docker安装jeecg-boot低代码开发平台(更新于2022.2.14)
开源项目:Linux系统docker安装jeecg-boot低代码开发平台(更新于2022.2.14)
1221 0
开源项目:Linux系统docker安装jeecg-boot低代码开发平台(更新于2022.2.14)
|
2月前
|
Python
解锁Python f-string:超越传统格式化的高效指南
解锁Python f-string:超越传统格式化的高效指南
|
2月前
|
设计模式 Java
【TMF】源码分析 1.0 LatticeClassLoader
LatticeClassLoader扩展Java双亲委派模型,支持多自定义类加载器的委托加载。类加载失败后依次尝试自定义加载器,实现插件化容错;资源获取优先父加载器,支持单资源查找与多资源聚合,适用于插件系统、多租户隔离及SPI扩展,保障业务隔离与灵活扩展。
123 1
|
7月前
|
存储 JSON 安全
Go语言切片,使用技巧与避坑指南
Go语言中的切片(Slice)是动态引用数组的高效数据结构,支持扩容与截取。本文从切片基础、常用操作到高级技巧全面解析,涵盖创建方式、`append`扩容机制、共享陷阱及安全复制等内容。通过代码示例详解切片特性,如预分配优化性能、区分`nil`与空切片、处理多维切片等。掌握这些核心知识点,可编写更高效的Go代码。
246 2
|
8月前
|
存储 机器学习/深度学习 安全
阿里云服务器计算型c8i与通用型g8i实例性能、适用场景及价格参考
阿里云不断推陈出新,致力于为用户提供高性能、高可靠性和高安全性的云服务器实例,以满足不同用户在各种复杂场景下的需求。其中,计算型c8i与通用型g8i实例凭借其卓越的性能和灵活的配置,成为了企业级用户的热门选择。本文将深入探讨这两款实例的性能特点、最新收费标准以及适用场景和活动价格情况,以供大家了解和选择。
|
5月前
|
存储 Ubuntu Linux
Ubuntu是Linux新手理想发行版的8个理由
信不信由你,Ubuntu仍然是初学者转向Linux时的首选。如果你打算在电脑上安装Ubuntu,可以考虑首先使用其现场启动功能测试环境。 Ubuntu 并不是唯一一个提供如此稳定性和卓越性能的操作系统。市场上也有基于 Ubuntu 的几个 Linux 发行版可供选择,鉴于每个发行版都建立在坚实的基础之上,它们之间的竞争可谓不相上下。 本文内容根据www.makeuseof.com网站上的文章总结和梳理而来, 如需了解更多信息,请访问该站点。
|
5月前
|
Ubuntu 安全 Linux
《Ubuntu 24.04.1版安装全攻略与实测体验》
综上所述,这次关于Ubuntu 24.04.1版的安装经历让我对新版本充满了期待,尽管细节上有些微的变化,但整体体验显得更加便捷易懂。在这一波Ubuntu新气象中,我期待与各位一起分享更多新鲜的体验与感受。
|
7月前
|
存储 缓存 数据挖掘
阿里云服务器实例选购指南:经济型、通用算力型、计算型、通用型、内存型性能与适用场景解析
当我们在通过阿里云的活动页面挑选云服务器时,相同配置的云服务器通常会有多种不同的实例供我们选择,并且它们之间的价格差异较为明显。这是因为不同实例规格所采用的处理器存在差异,其底层架构也各不相同,比如常见的X86计算架构和Arm计算架构。正因如此,不同实例的云服务器在性能表现以及适用场景方面都各有特点。为了帮助大家在众多实例中做出更合适的选择,本文将针对阿里云服务器的经济型、通用算力型、计算型、通用型和内存型实例,介绍它们的性能特性以及对应的使用场景,以供大家参考和选择。
|
机器学习/深度学习 人工智能 自然语言处理
360Zhinao2-7B:360推出自研360智脑大模型的升级版
360Zhinao2-7B是360自研的AI大模型360智脑7B参数升级版,涵盖基础模型及多种上下文长度的聊天模型。该模型在语言理解与生成、聊天能力、数学逻辑推理等方面表现出色,支持多语言和多上下文长度,适用于多种商业应用场景。
521 23
360Zhinao2-7B:360推出自研360智脑大模型的升级版

热门文章

最新文章