HDU 1053 && PKU 1521 Entropy (PKU 3253, HDU 2527同解)
2010-05-29 16:06
381 查看
Huffman编码, 题意:给你一个序列,output the length in bits of the 8-bit ASCII encoding, the length in bits of an optimal prefix-free variable-length encoding, and the compression ratio accurate to one decimal point.
其实就是要你构造最优前缀树, 也就是Huffman树, 求它的带权路径和。 刚开始每种字符代表一个根节点, 它出现的次数就是其权值, 接下来就是求构造的Huffman树的带权路径和了。
刚开始比较傻, 先建立了Huffman树的二叉链表,然后通过先序遍历求它的带权路径和。
code:
后来发现不用建树的, 因为是求树的带权路径长度, 根据权值可以直接求得。
其实就是要你构造最优前缀树, 也就是Huffman树, 求它的带权路径和。 刚开始每种字符代表一个根节点, 它出现的次数就是其权值, 接下来就是求构造的Huffman树的带权路径和了。
刚开始比较傻, 先建立了Huffman树的二叉链表,然后通过先序遍历求它的带权路径和。
code:
2496390 | 2010-05-28 12:34:39 | Accepted | 1053 | 0MS | 256K | 1670 B | G++ | xwc-hdu |
#include <cstdio> #include <cstring> using namespace std; char str[1010]; bool hash[1010]; int num[220]; typedef struct BitNode { int data; BitNode *lchild, *rchild; BitNode() { lchild = NULL; rchild = NULL; } }*BitTree; BitTree T[1010]; int sum; int Min(BitTree T[], int k)//求最小权值的根,返回根的下标 { int min, i; T[k] = new BitNode; T[k]->data = 0x3fffffff; min = k; for (i = 0; i < k; i++) { if (!hash[i] && T[i]->data < T[min]->data) min = i; } hash[min] = true; return min; } void Allsum(BitTree &T, int num)//先序求带权路径和 { if (T) { num++;//num表示该路径上经过的节点个数 if (!T->lchild && !T->rchild) { sum += (num - 1) * T->data; return ; } Allsum(T->lchild, num); Allsum(T->rchild, num); } } int main() { int k, i, ans1; while (scanf("%s", str) != EOF) { if (strcmp(str, "END") == 0) break; memset(num, 0, sizeof(num)); memset(hash, false, sizeof(hash)); for (i = 0; str[i]; i++) { num[str[i]]++; } k = 0; for (i = 0; i < 150; i++) { if (num[i] != 0) { T[k] = new BitNode; T[k++]->data = num[i]; } } if (k == 1)//即表示只出现一个字符,最短编码长度即字符串长度 { ans1 = strlen(str) * 8; sum = strlen(str); printf("%d %d %.1lf/n", ans1, sum, ans1 * 1.0/sum); continue; } int len = k; while (--len) { int tmp1 = Min(T, k); int tmp2 = Min(T, k); T[k] = new BitNode; T[k]->lchild = T[tmp1]; T[k]->rchild = T[tmp2]; T[k]->data = T[tmp1]->data + T[tmp2]->data; k++; } BitTree root = new BitNode; root = T[k-1]; sum = 0; Allsum(root, 0); ans1 = strlen(str) * 8; printf("%d %d %.1lf/n", ans1, sum, ans1 * 1.0/sum); } return 0; }
后来发现不用建树的, 因为是求树的带权路径长度, 根据权值可以直接求得。
#include <cstdio> #include <cstring> #include <queue> #include <vector> using namespace std; int main() { char str[1010]; int i, test, k, nn, m, current, sum, num[150]; priority_queue<int, vector<int>, greater<int> >Q; while (scanf("%s", str) != EOF) { if (strcmp(str, "END") == 0) break; while (!Q.empty()) Q.pop(); memset(num, 0, sizeof(num)); for (i = 0; str[i]; i++) { num[str[i]]++; } k = 0; for (i = 'A'; i <= 'Z'; i++) { if (num[i] != 0) { Q.push(num[i]); k++; } } if (num['_'] != 0) { Q.push(num['_']); k++; } nn = k; sum = 0; while (--k) { current = Q.top(); Q.pop(); current += Q.top(); Q.pop(); sum += current; Q.push(current); } if (nn == 1) sum = strlen(str); int ans1 = strlen(str) * 8; printf("%d %d %.1lf/n", ans1, sum, ans1 * 1.0/sum); } return 0; }
相关文章推荐
- hdu-1053-Entropy && poj-1521-Entropy (哈夫曼编码)
- HDU 1053 & HDU 2527 哈夫曼编码
- hdu 1053 Entropy
- hdu 1053 Entropy (哈夫曼编码)
- HDU 1053 Entropy
- hdu 2527 Safe Or Unsafe<multiset>
- hdu 1828 && pku 1177 Picture
- hdu 5.2.7 1053 Entropy
- HDU_1053 Entropy
- pku 2104 K-th Number && hdu 2665 Kth number 划分树
- hdu 1053 Entropy (哈夫曼树)
- HDU - 1053 Entropy
- hdu 1053 Entropy (哈夫曼树)
- Hdu 1053 Entropy
- hdu 1688 Sightseeing (次短路及次短路数)&&pku3255 Roadblocks &&3191 How Many Paths Are There
- hdu 1533 && pku 2195 最小费用最大流
- hdu 1053 Entropy(霍夫曼树)
- 哈夫曼树 HDU 1053 HDU 2527
- pku 1521 赫夫曼编码 Entropy 解题报告
- HDU 1053 Entropy(huffman 编码)