描述
实践是检验真理的唯一标准。
很多课程只有亲手实践才会真正掌握。一起看看下面的关于课本上的Huffman Code的问题吧
现在有篇文章,请用二进制前缀编码对文章中出现所有字符进行其编码,使编码后的文章总长最短。
这正是课本上Huffman Code所解决的问题。来试试吧!
-
输入
-
多组输入,第一个正整数T表示组数。
每组第一行有一个正整数n,1≤n≤100000表示所用的字符种数。
接下来一行为n个正整数,表示每个字符在文章中出现的次数。
输出
-
输出编码的最小长度
样例输入
-
131 2 3
样例输出
-
9
此题采用堆排序
#include <iostream>
#include <ctime>
using namespace std;
int a[100002];
void swap(int& a, int& b)
{
int temp = a;
a = b;
b = temp;
}
void heapAdjust(int h[], int s, int m)
{
int rc = h[s];
int j;
for(j = 2 *s; j <= m; j *= 2)
{
if(j < m && h[j + 1] < h[j])
{
j ++;
}
if(rc <= h[j])
{
break;
}
h[s] = h[j];
s = j;
}
h[s] = rc;
}
int calc_huff(int h[], int n)
{
int i;
for(i = n / 2; i > 0; i --)
{
heapAdjust(h, i, n);
}
i = n;
int sum = 0;
while(i > 1)
{
swap(h[1], h[i]);
heapAdjust(h, 1, i - 1);
i --;
swap(h[1], h[i]);
heapAdjust(h, 1, i - 1);
sum = sum + h[i] + h[i + 1];
h[i] = h[i] + h[i + 1];
}
return sum;
}
int main()
{
int t;
cin >> t;
while(t --)
{
int n;
cin >> n;
int i;
for(i = 1; i <= n; i ++)
{
cin >> a[i];
}
cout << calc_huff(a, n) << '\n';
}
return 0;
}