傳送門:HDU 1053 Entropy
分析:
就是簡單的模擬題。
模擬哈夫曼樹的構建過程。
技巧:利用tmp中間數組做中轉模擬構建過程。
詳見代碼:
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int num[27];
int fun()
{
int n = 0,i,j,l;
sort(num, num+27); // 按出現次數從小到大排序 也就是按頻率升序排序
int tmp[27],k = 0;
for(i = 0; i < 27; i ++)
if(num[i] != 0)
break;
// index [0,26]
l = 27-i; // l 表示出現的字母個數
if(l == 1)
return num[26];
for(i = 27-l; i < 27; i ++)
tmp[k++] = num[i];
// 模擬哈夫曼的構造過程(l個點 只需要構建l-2次)
for(i = 0; i < l - 1; i ++) {
if(i%2==0){
num[0] = tmp[0] + tmp[1];
n += num[0]; // 累加長度
for(j=2; j<k; j++)
num[j-1] = tmp[j];
k--; // 所有點的個數-1 (2點已合1點)
sort(num, num+k); // 組合一次就重新排序
}
else{
tmp[0] = num[0]+num[1];
n += tmp[0]; // 累加長度
for(j=2; j<k; j++)
tmp[j-1] = num[j];
k--;
sort(tmp, tmp+k); // 組合一次就重新排序
}
}
return n;
}
char str[1001];
int main()
{
int len,i;
int original, now;
while(scanf("%s", str)&&strcmp(str,"END")!=0){
memset(num, 0, sizeof(num));
len = strlen(str);
for(i = 0; i < len; i ++) {
if(str[i]-'A'<26)
num[str[i]-'A'] ++;
else
num[26] ++; // 下劃線
}
original = 8*len;
now = fun(); // 哈夫曼二進制壓縮 返回壓縮位數
printf("%d %d %.1lf\n", original, now, 1.0*original/now);
}
return 0;
}