poj 1521
http://poj.org/problem?id=1521
题意:给你一个字符串,首先是计算出一个按正常编码的编码长度,其次是计算出一个用霍夫曼编码的编码长度,最后求正常编码的长度除以霍夫曼编码长度的值,保留一位小数。
思路:正常的编码长度的话,由于都是ASCII码值所以编码长度都为8,所以总长度就是8*字符串的长度Len,然后霍夫曼编码的话,discuss里面很多人都是用优先队列,用优先队列的话,就不用自己维护了,我没用采用优先队列,而是一直维护一个递减的数组,这样的效果和有优先队列是一样的。
霍夫曼编码的示意图

我在这里假设,A有10个,B有5个,C有3个,D有一个。
那么霍夫曼编码的话,就是这样编的。
而这道题是求霍夫曼编码的编码长度。
为什么C和D会比B要多一个编码长度,因为C和D在树枝上要比B要多一个分叉点,那么那个如果没有这个分叉点的话,C和D的编码长度就是和B的一样。
那么我们就可以首先用个把最少的两个字符数加起来,因为在现阶段每个字符都可以看出是只有一个0或者1编码编成的。然后把这两个字符合并起来,意思就是我可以看成没有D这个元素,而是有4个C。
这样就少了一个分叉点,这4个C又和5个B构成了一个分叉点。在现阶段,我们又可以把这5个B和4个C看成只有1个编码长度(0或1)构成的,然后把这两个字符的数加起来,在把这两个字符合并。
相当于只有10个A和9个B构成的。然后A就由0编码,B就由1编码,在把他们两个字符数相加,在合并,最后就相当于有19个A了。然后就编码就结束了。
这里或许有些人会不理解,其实你想,比如说D加了几次。首先D是在和C合并之前就加了一次,然后,D就被C包含了。然后C再和B合并之前有加了一次,这里就相当于D有又加了一次,最后B又包含了C,
最后B在和A合并之前又加了一次,这就可以说明。D是被加了3次的。D的编码长度也就是3,在上面图示上的D的编码也就是111.
每个分叉点的数目都是它下面所有的分支的数目和。而下面的分支在合并之前就加了一次。
#include <stdio.h>
#include <string.h>
#include <stdlib.h> char inp[]; int s[]; int cmp(const void *a,const void *b)
{
return (*(int *)b)-(*(int *)a);
} int main()
{
while(scanf("%s",inp),strcmp(inp,"END")!=)
{
int ans=;
memset(s,,sizeof(s[]));
int len=strlen(inp);
for(int i=;i<len;i++)
s[inp[i]]++;
qsort(s,,sizeof(s[]),cmp);
if(s[]==len) ans=len;
else while(s[]!=len){
int i=;
for(;s[i]!=;i++); //这里注意有个分号,目的是找出它的最小的那个点。
ans+=s[--i];
ans+=s[i-];
s[i-]+=s[i];
s[i]=;
qsort(s,i,sizeof(s[]),cmp); //霍夫曼编码,是从最小的那两个开始编的。
}
printf("%d %d %.1f\n",len*,ans,1.0*len*/ans);
memset(inp,,sizeof(inp));
}
return ;
}
poj 1521的更多相关文章
- [POJ 1521]--Entropy(哈夫曼树)
题目链接:http://poj.org/problem?id=1521 Entropy Time Limit: 1000MS Memory Limit: 10000K Description A ...
- Poj(1521),哈夫曼编码
题目链接:http://poj.org/problem?id=1521 这里,网上有很多博客都有写,很多人没有建树,直接就是求一下这个哈夫曼编码的长度,的确很巧妙,我也用的这个方法,但是,几乎所有博客 ...
- 【霍夫曼树】 poj 1521 Entropy
poj.org/problem?id=1521 注意只有特殊情况:只有一种字母 #include<iostream> #include<cstdio> #include< ...
- POJ推荐50题
此文来自北京邮电大学ACM-ICPC集训队 此50题在本博客均有代码,可以在左侧的搜索框中搜索题号查看代码. 以下是原文: POJ推荐50题1.标记“难”和“稍难”的题目可以看看,思考一下,不做要求, ...
- poj 1719 Shooting Contest
http://poj.org/problem?id=1719 Shooting Contest Time Limit: 1000MS Memory Limit: 10000K Total Subm ...
- POJ 3370. Halloween treats 抽屉原理 / 鸽巢原理
Halloween treats Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 7644 Accepted: 2798 ...
- POJ 2356. Find a multiple 抽屉原理 / 鸽巢原理
Find a multiple Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7192 Accepted: 3138 ...
- POJ 2965. The Pilots Brothers' refrigerator 枚举or爆搜or分治
The Pilots Brothers' refrigerator Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 22286 ...
- POJ 1753. Flip Game 枚举or爆搜+位压缩,或者高斯消元法
Flip Game Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 37427 Accepted: 16288 Descr ...
随机推荐
- SSL、OPENSSL、SSH、OPENSSH
SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议.TLS与 ...
- Jetty多Connector
有时候想要启动两个端口,或者通过一个Jetty server提供多个不同服务,比如说使用8080来指定默认访问端口,使用8433指定https访问端口等等,此时就可以通过创建多个Connector来解 ...
- 【8-19】java学习笔记01
JDK API文档 java SE 8 API文档:http://www.oracle.com/technetwork/java/javase/documentation/jdk8-doc-downl ...
- js中的全局变量和静态变量的使用, js 的调试?- 如果js出错, js引擎 就会停止, 这会 导致 后面的 html中 refer 该函数时, 会报错 函数为定义!!
效果里面的函数, 如show, hide,slideDown等, 这些都叫 "效果"函数, 但是里面可以包含动画, 也可以 不包含动画. 动画,是指 元素 的内容 是 逐渐 显示/ ...
- 开机自动连接/断开VPN 批处理
或许大家在工作或生活中有接触到VPN,如果使用Windows自带的VPN来连接,每次开机要像宽带拨号那样,右击该VPN连接图标,然后选择“连接”(如果未记住密码甚至还要输入密码),然后点击确定,有点麻 ...
- 【转】MySQL数据类型和常用字段属性总结
来源:http://www.jb51.net/article/55853.htm 这里先总结数据类型.MySQL中的数据类型大的方面来分,可以分为:日期和时间.数值,以及字符串.下面就分开来进行总结. ...
- 4. Linux常用命令
1. ls 查看当前目录信息 2. pwd 查看当前目录 3. cd 切换目录 快捷操作:cd - 可快速对最近的两个目录切换, cd 或者cd~ 直接回到用户自己的主目录, 4. hwclock ...
- HLOI2016滚粗记
首先,别问我HLOI是哪里....HLJ = 黑龙江... 这次的省选总结起来还是由于我太弱,考试的时候状态不好,连个线段树都没想出来 坐了好久的火车到哈尔滨,车上打了一会扑克,感觉没过多长时间就到了 ...
- BZOJ2631——tree
1.题目大意:bzoj1798的lct版本 2.分析:这个把线段树改成splay就好 #include <stack> #include <cstdio> #include & ...
- 联合主键用Hibernate注解映射的三种方式
第一.将联合主键的字段单独放在一个类中,该类需要实现java.io.Serializable接口并重写equals和hascode,再将该类注解为@Embeddable,最后在主类中(该类不包含联合主 ...