题解:如图,哈夫曼编码,不断选取规模最小的两个连接,如样例AAAAABCD,A规模为5,B规模为1,C规模为1,D规模为1,那么A取0,BCD为10,110,111时编码长度最短,那么就是C与D先合并,如图中1,2节点,变为规模为2的点,然后与B(3)相连,最后和A(4)连接。其实题目不需要建立哈夫曼树,只要运用其原理即可,就和合并果子是一样的。
图被百度吞了,谴责一下……
#include <cstdio> #include <cstring> #include <queue> using namespace std; char line[10000]; int hash[27],len; int main(){ while(scanf("%s",line)){ if(strcmp(line,"END")==0)break; memset(hash,0,sizeof hash); len=strlen(line); for(int i=0;i<len;i++){ if(line[i]=='_')hash[0]++; else hash[line[i]-'A'+1]++; } int flag=0; for(int i=0;i<27;i++){ if(hash[i]==len){ printf("%d %d 8.0 ",len*8,len); flag=1; break; } } if(flag)continue; priority_queue<int,vector<int>,greater<int> > q; int ans=0,a,b; for(int i=0;i<27;i++)if(hash[i]!=0)q.push(hash[i]); while(1){ int a=q.top();q.pop(); if(q.empty())break; int b=q.top();q.pop(); ans+=a+b; q.push(a+b); } printf("%d %d %.1lf ",len*8,ans,len*8.0/ans); } return 0; }