POJ1521(哈夫曼编码)(贪心+优先队列)

地址:http://poj.org/problem?id=1521

题意:

就是给定一个串,求原长度和哈夫曼编码后的长,并求比值

解析:

并不需要构建哈夫曼树,由于构建哈夫曼树的过程,是每次找队列中最小的两个进行合并,所以定义一个小为头的优先队列,每次取最小的两个,累加后,再相加放回去。

G++会WA,用C++交

#include<iostream>
#include<cstring>
#include<stack>
#include<queue>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=1e3+50;
char s[maxn];
int ch[29];
//priority_queue<int, vector<int>, greater<int> > Q; 最小的在队首 
int main()
{
    while(scanf("%s",s))
    {
        int len=strlen(s);
        if(len==3&&s[0]=='E'&&s[1]=='N'&&s[2]=='D')
            break;
        sort(s,s+len);
        int cnt=1;
        priority_queue<int, vector<int>, greater<int> > Q;
        for(int i=1;i<len;i++)
        {
            if(s[i]!=s[i-1])
            {
                Q.push(cnt);
                cnt=1;
            }
            else
                cnt++;
        }    int sum=0;
        Q.push(cnt);  //最后会漏掉一个
        if(Q.size()==1)  //字符串只有一种的情况。
            sum=Q.top();
    
        while(Q.size()>1)
        {
            int a=Q.top();Q.pop();
            int b=Q.top();Q.pop();
            sum+=a+b;
            Q.push(a+b);            
        }
//        if(sum==0)
//            sum=Q.top();
        printf("%d %d %.1lf\n",len*8,sum,(double)(len*8*1.0)/(sum*1.0));
    }
}

 

posted @ 2020-08-07 17:09  liyexin  阅读(340)  评论(0编辑  收藏  举报