首页 > 其他分享 >【UVA 12676】Inverting Huffman 题解(哈夫曼树)

【UVA 12676】Inverting Huffman 题解(哈夫曼树)

时间:2023-09-21 14:04:11浏览次数:32  
标签:字符 哈夫曼 int 题解 代码 12676 权值 长度 节点

静态霍夫曼编码是一种主要用于文本压缩的编码算法。给出的文本为 由N个不同字符组成的特定大小,算法选择N个代码,每个代码对应一个不同的字符 性格使用这些代码压缩文本。为了选择代码,算法构建一个 有N片叶子的二元根树。对于N≥2,树可按如下方式构建。 1.对于文本中的每个不同字符,构建一个仅包含单个节点的树,并将其分配给它 与文本中字符出现次数一致的权重。 2.建立一个包含上述N棵树的集合。 3.当s包含多个树时: (a) 选择具有最小权重的t1∈s,并将其从s中删除。 (b) 选择具有最小权重的t2∈s,并将其从s中删除。 (c) 构建一个新的树t,t1作为其左子树,t2作为其右子树,并将 t1和t2的权重之和。 (d) 将t包含在s中。 4.返回s中唯一保留的树。 对于文本“abracabra”,通过上述过程生成的树可以看起来像 下图左侧,其中每个内部节点都标有子树根的权重 在该节点处。注意,获得的树也可以看起来像图片右侧的树,其中 因为在步骤3a和3b,集合s可以包含具有最小权重的若干树。 对于文本中的每个不同字符,其代码取决于最终树中存在的路径, 从根到对应于字符的叶。代码的长度是边的数量 这与路径中的内部节点的数量一致)。假设树打开 左边是由算法构建的,“r”的代码长度为3,而“d”的代码的长度为4。 您的任务是,给定算法选择的N个代码的长度,找到最小大小(总计 字符数),以便生成的代码具有N个长度。

【UVA 12676】Inverting Huffman 题解(哈夫曼树)_#include

输入 输入文件包含几个测试用例,每个测试用例如下所述。 第一行包含表示不同字符数的整数N(2≤N≤50) 出现在文本中的。第二行包含N个整数Li 指示代码的长度 通过霍夫曼算法为不同字符选择(i=1,2,…,N时,1≤Li≤50)。你可以 假设至少有一棵树,按照所述构建,生成具有给定长度的代码。 输出 对于每个测试用例,输出一行,其中一个整数表示最小大小( 字符),以便生成的代码具有给定的长度。

样本输入 2. 1 1 4. 2 2 2 2 10 8 2 4 7 5 1 6 9 3 9 样本输出 2. 4. 89

思路

输入数据的同时,求树的最大深度d,即最长编码长度。根据输入的编码长度,在对应的层插入权值为0的节点。从树的最大深度处,即最底层开始,向上推导。

lastMax为下一层权值最大节点的权值,由于最底层没有下一层,而最底层的权值只能为1,所以最底层的lastMax记为1。

该层未知权值的节点,在初始化时权值被设置为0,该层所有节点权值的最小值为下一层权值最大节点的权值,所以将权值为0的节点的权值全部设置为lastMax。将该层用sort排序,每两个节点合并后插入上一层,该层权值最大的节点的权值赋值给lastMax。

到达树根后,输出树根的权值,即最小字符数。

AC代码

#include <iostream>
#include <vector>
#include <algorithm>
#define AUTHOR "HEX9CF"
using namespace std;

int main()
{
    int n, l;
    int d;
    vector<long long> v[60];
    while (cin >> n)
    {
        d = 0;
        for (int i = 0; i < n; i++)
        {
            v[i].clear();
        }
        for (int i = 0; i < n; i++)
        {
            cin >> l;
            v[l].push_back(0);
            d = max(d, l);
        }
        long long lasMax = 1;
        for (int i = d; i > 0; i--)
        {
            for (int j = 0; j < v[i].size(); j++)
            {
                if (!v[i][j])
                {
                    v[i][j] = lasMax;
                }
            }
            sort(v[i].begin(), v[i].end());
            for (int j = 0; j < v[i].size(); j += 2)
            {
                v[i - 1].push_back(v[i][j] + v[i][j + 1]);
            }
            lasMax = *(v[i].end() - 1);
        }
        cout << *(v[0].begin()) << endl;
    }
    return 0;
}

标签:字符,哈夫曼,int,题解,代码,12676,权值,长度,节点
From: https://blog.51cto.com/HEX9CF/7553379

相关文章

  • 题解 UVA1537 Picnic Planning
    这道题在显然是最小生成树,但是很显然我是不会打最小生成树的。题意描述给定一张\(n\)个点\(m\)条边的无向图,求出无向图的一棵最小生成树,满足一号节点的度数不超过给定的整数\(s\)。具体思路首先,看到这种度数最多为\(s\)的题,显然想到wqs二分。但是wqs二分是恰好选......
  • 【HarmonyOS】【FAQ】HarmonyOS应用开发相关问题解答(四)
    ​贴接上回。。。 【往期FAQ参考】【HarmonyOS】【FAQ】HarmonyOS应用开发相关问题解答(一)【HarmonyOS】【FAQ】HarmonyOS应用开发相关问题解答(二)【HarmonyOS】【FAQ】HarmonyOS应用开发相关问题解答(三) 【本期FAQ】1、JS服务卡片能实现按钮触摸时更换背景色,离开恢复原来......
  • ABC319题解
    直接从D开始了。D可可爱爱的二分捏。check就按照题目里写的就行了。然后\(l\)的初值要注意一下,就是\(\max^{i\len}_{i=1}a_i\)。代码:#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;constintmaxn=2e5+10;intn,m;inta[maxn];intl,......
  • Friendly Arrays题解
    2023-09-18题目FriendlyArrays难度&重要性(1~10):5题目来源luogu题目算法贪心解题思路一道大水题。这道题解法非常的套路,我们需要对于处理按位或和按位异或时,首先就要把数拆成二进制的形式去考虑。首先我们需要简单了解一下按位或和按位异或的运算规则:按位或,对于两......
  • 使用dom4j解析xml文件及selectNodes取不到值问题解决
    参考文档:https://blog.csdn.net/PARADDD/article/details/131307189https://blog.csdn.net/weixin_37703598/article/details/81273199......
  • asp.net 跨域问题解决
    前言:近期在对接前后端分离的项目中遇到了跨域问题,查了一些资料都比较新,没有比较老的解决方式所以记录一下背景如下:后端最老的aspx前端vue3部署在iis上1.跨域的处理点击查看代码<httpProtocol> <customHeaders> <addname="Access-Control-Allow-Origin"value=......
  • 【POJ 3278】Catch That Cow 题解(广度优先搜索)
    农夫约翰已被告知一头逃亡奶牛的位置,并想立即抓住她。他从一条数字线上的N点(0≤N≤100000)开始,奶牛在同一条数字线上的K点(0≥K≤100000)。农夫约翰有两种交通方式:步行和坐车。*步行:FJ可以在一分钟内从任何点X移动到点X-1或X+1*坐车:FJ可以在一分钟内从任何X点移动到2×X点。如果奶......
  • 题解 [ARC165C] Social Distance on Graph
    赛时:看不懂题,啊这!赛后:就这?题目描述有一个简单相连的无向图,其顶点数为\(n\),编号为\(1\)至\(n\)。图中有\(m\)条加权边,第\(i\)条边连接顶点\(a_i\)和\(b_i\),权重为\(w_i\)。此外,连接两个顶点的简单路径的权重是简单路径中包含的边的权重之和。我们给每个顶点涂上红......
  • QOJ61 Cut Cut Cut! 题解
    题面。题解假设\(1\)号点有\(d\)条出边,给\(d\)条出边赋\(d\)个独立的单位向量,接下来,每个出边记作入边的随机线性组合,那么对于第\(i\)个点,答案就是入边生成的线性空间的秩。正确性证明:对于每个点考虑,假设现在考虑\(i\)号点,将其入边集合记作\(E1_{i}\),出边集合记......
  • 9.20周三(动手动脑问题解决)
    无法编译原因:没有默认构造推出结论:当你给类提供了一个自定义的构造方法,导致系统不在提供默认构造方法了,需要自己提供初始化测试packageorg.example;publicclassInitializeBlockClass{publicintfield=100;{field=200;}publicInitiali......