HDU 2527 Safe Or Unsafe(哈夫曼编码)
2015-10-06 22:20
417 查看
Safe Or Unsafe
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Problem Description
Javac++ 一天在看计算机的书籍的时候,看到了一个有趣的东西!每一串字符都可以被编码成一些数字来储存信息,但是不同的编码方式得到的储存空间是不一样的!并且当储存空间大于一定的值的时候是不安全的!所以Javac++ 就想是否有一种方式是可以得到字符编码最小的空间值!显然这是可以的,因为书上有这一块内容--哈夫曼编码(Huffman Coding);一个字母的权值等于该字母在字符串中出现的频率。所以Javac++ 想让你帮忙,给你安全数值和一串字符串,并让你判断这个字符串是否是安全的?
Input
输入有多组case,首先是一个数字n表示有n组数据,然后每一组数据是有一个数值m(integer),和一串字符串没有空格只有包含小写字母组成!
Output
如果字符串的编码值小于等于给定的值则输出yes,否则输出no。
Sample Input
2
12
helloworld
66
ithinkyoucandoit
Sample Output
no
yes
/************************************************************************/
数据结构:哈夫曼树。
这道题考察的是数据结构中的哈夫曼树。
做法:是先根据输入的字符串s确定其叶子节点及其各叶子节点的权值,然后创建哈夫曼树,再根据哈夫曼树求每一个叶子节点的哈夫曼编码。最后根据求得的哈夫曼编码(路径长度)和各叶子节点的权值求的这棵哈夫曼树的带权路径长度(WPL)。
其中创建哈夫曼树和求哈夫曼编码都可以在数据结构的书上找到模板,你需要做的就是根据s确定叶子节点和权值以及求WPL(WPL即为最后要比较的值)。
需要注意的是,当s只有一种字符的情况下,哈夫曼树是构造不起来的,需要特殊处理(直接比较)。一开始没有注意这个细节,提交了的结果是WA,后来看了Discuss才知道。
这是我第一次做哈夫曼编码的题,自己尝试模板什么的都不看,写出来的成果,虽然不知道写得好不好,但是至少能过了此题
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h> #include<string.h> #include<stdlib.h> #include<queue> #include<stack> #include<math.h> #include<vector> #include<map> #include<set> #include<stdlib.h> #include<cmath> #include<string> #include<algorithm> #include<iostream> #define exp 1e-10 using namespace std; const int N = 10005; const int inf = 1000000000; const int mod = 2009; int w[26]; struct node { int k,sum; char ch[30]; node(){} node(int k0,int sum0,char ch0) { sum=sum0;k=k0; ch[0]=ch0; } node(int k1,int k2,int sum0,char *t1,char *t2) { sum=sum0;k=k1+k2; for(int i=0;i<k1;i++) ch[i]=t1[i],w[t1[i]-'a']++; for(int i=0;i<k2;i++) ch[i+k1]=t2[i],w[t2[i]-'a']++; } bool operator < (const node &a) const { return sum>a.sum;//最小值优先 } }; char s ; int main() { int t,n,i,sum; scanf("%d",&t); while(t--) { priority_queue<node> q; memset(w,0,sizeof(w)); scanf("%d",&n); scanf("%s",s); for(i=0;s[i]!='\0';i++) w[s[i]-'a']++; for(i=0;i<26;i++) if(w[i]) q.push(node(1,w[i],i+'a')); memset(w,0,sizeof(w)); if(q.size()==1) { if(strlen(s)>n) puts("no"); else puts("yes"); continue; } while(q.size()>1) { node u1=q.top(); q.pop(); node u2=q.top(); q.pop(); q.push(node(u1.k,u2.k,u1.sum+u2.sum,u1.ch,u2.ch)); } node u=q.top(); q.pop(); for(i=sum=0;s[i]!='\0';i++) sum+=w[s[i]-'a']; if(sum>n) puts("no"); else puts("yes"); } return 0; }菜鸟成长记
相关文章推荐
- HTML页面跳转的5种方式
- JQuery表单元素过滤选择器
- JS获取当前/指定URL参数
- css3 多行文本 溢出 省略号
- JS 封装
- javascript原来还可以这样玩
- Json 解析
- Extjs extjs datefield日期格式
- 【笔试】55、实现吧字符串转化为数字(C的atoi函数)
- javascript创建对象常用方法
- Nodejs安装
- HTML5移动Web开发(九)——优化浏览器视口宽度设置
- 剑指offer:不用加减乘除做加法
- JS 闭包
- 关于mysql_affected_rows()
- 剑指offer:孩子们的游戏(圆圈中最后剩下的数)
- 剑指offer:翻转单词顺序列
- jquery实现checkbox全选反选
- 我的Web学习之路2——密码框的提示与表单验证
- JSP include