贪心、哈夫曼编码——Entropy POJ - 1521
https://vjudge.net/problem/POJ-1521
利用哈夫曼的思想,可以直接计算编码的总长度,跳过编码的过程。
哈夫曼编码介绍
#include<iostream>
#include<queue>
#include<string>
#include<algorithm>
//#include<vector>并不需要
using namespace std;
int main(void) {
string s;
priority_queue< int, vector< int >, greater <int> > Q;
//这种写法表示升序排序,降序是less
while(getline(cin, s) && s != "END"){
int t = 1;
sort(s.begin(), s.end());//对字符串排序,方便计算字母频次
for (int i = 1; i < s.length(); i++) {
if (s[i] != s[i - 1]) {//计算字母频次
Q.push(t);
t = 1;
}
else
t++;
}
Q.push(t);
int ans = 0;
if (Q.size() == 1) ans = Q.top();//哈夫曼无法处理一种字符,此时长度就是它的频次
while (Q.size() > 1) {//因为要连续取出两个元素,所以不能用!Q.empty()
int a = Q.top(); Q.pop();
int b = Q.top(); Q.pop();
// printf("%d + %d\n", a, b);
Q.push(a + b);
ans += (a + b);
}
Q.pop();
int ans2 = s.length() * 8;
printf("%d %d %.1lf\n", ans2, ans, double(ans2) / ans);
}
return 0;
}