题意:根据哈夫曼编码原则压缩一个字符串,问压缩后的大小和压缩比。
思路:就是写一棵哈夫曼树。
http://acm.hdu.edu.cn/showproblem.php?pid=1053
ps:第一次写哈夫曼树,写得好丑
#include <map>
#include <set>
#include <queue>
#include <cmath>
#include <ctime>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define rep(i,a,b) for(int i = (a) ; i <= (b) ; i ++)
#define rrep(i,a,b) for(int i = (b) ; i >= (a) ; i --)
#define repE(p,u) for(Edge * p = G[u].first ; p ; p = p -> next)
#define cls(a,x) memset(a,x,sizeof(a))
#define eps 1e-8
using namespace std;
const int MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e5+5;
const int MAXE = 2e5+5;
typedef long long LL;
typedef unsigned long long ULL;
int T,n,m,k;
int fx[] = {0,1,-1,0,0};
int fy[] = {0,0,0,-1,1};
char s[100005];
int a[30];
int tot = 0;
struct leaf {
int x,y;
int zero;
char c;
int num;
}t[1000];
struct Node {
int num;
int addr;
Node(int _num,int _addr) {
num = _num ; addr = _addr ;
}
bool operator < (const Node B) const {
return num > B.num;
}
};
priority_queue<Node>p;
int ans ;
void dfs(int u,int depth) {
if(t[u].x == 0) {
ans += depth * t[u].num;
return ;
}
dfs(t[u].x,depth+1);
dfs(t[u].y,depth+1);
}
void Huffman() {
while(!p.empty())p.pop();
rep(i,0,25) {
if(a[i]) {
p.push(Node(a[i],tot));
t[tot].x = t[tot].y = 0;
t[tot].c = i + 'A';
t[tot].num = a[i];
tot ++;
}
}
if(a[26]) {
p.push(Node(a[26],tot));
t[tot].x = t[tot].y = 0;
t[tot].c = '_';
t[tot].num = a[26];
tot ++;
}
if(p.size() == 1) {
ans = strlen(s);
return ;
}
while(p.size() != 1) {
Node tmp1 = p.top();p.pop();
Node tmp2 = p.top();p.pop();
t[tmp1.addr].zero = 0; t[tmp2.addr].zero = 1;
t[tot].x = tmp1.addr ; t[tot].y = tmp2.addr;
p.push(Node(tmp1.num+tmp2.num,tot));
tot ++;
}
ans = 0;
dfs(tot-1,0);
}
void input() {
}
void solve() {
int len = strlen(s);
cls(a,0);
rep(i,0,len-1) {
if(s[i] == '_') a[26] ++;
else a[s[i]-'A'] ++;
}
tot = 1;
Huffman();
printf("%d %d %.1lf\n",len*8,ans,(double)(len*8)/(double)ans);
}
int main(void) {
while(~scanf("%s",s)) {
if(strcmp(s,"END") == 0) break;
input();
solve();
}
return 0;
}