hdu2527哈夫曼編碼

/*
Safe Or Unsafe
Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1816    Accepted Submission(s): 736


Problem Description
Javac++ 一天在看計算機的書籍的時候,看到了一個有趣的東西!每一串字符均可以被編碼成一些數字來儲存信息,可是不一樣的編碼方式獲得的儲存空間是不同的!而且當儲存空間大於必定的值的時候是不安全的!因此Javac++ 就想是否有一種方式是能夠獲得字符編碼最小的空間值!顯然這是能夠的,由於書上有這一塊內容--哈夫曼編碼(Huffman Coding);一個字母的權值等於該字母在字符串中出現的頻率。因此Javac++ 想讓你幫忙,給你安全數值和一串字符串,並讓你判斷這個字符串是不是安全的?


Input
輸入有多組case,首先是一個數字n表示有n組數據,而後每一組數據是有一個數值m(integer),和一串字符串沒有空格只有包含小寫字母組成!


Output
若是字符串的編碼值小於等於給定的值則輸出yes,不然輸出no。


Sample Input

2
12
helloworld
66
ithinkyoucandoit



Sample Output

no
yes



Source
HDU 2008-10 Programming Contest
*/
#include <iostream>
#include<stdio.h>
#include <queue>
using namespace std;
const int strLen=100000;
struct Node
{
    int value;
    Node* left;
    Node* right;
} node[26];
bool operator<(Node a,Node b)
{
    return a.value>b.value;
}
int WPL(Node* head)
{
    int wpl=0;
    if(head)
    {
        if(head->left&&head->right)
            wpl+=head->value;
        wpl+=WPL(head->left)+WPL(head->right);
    }
    return wpl;
}
int main()
{
    int n,m,i,wpl,wpl2;
    char ch[strLen];
    Node*head,*tp,*tp1,*tp2;
    scanf("%d",&n);
    while(n--)
    {
        head=NULL;
        wpl=0;
        scanf("%d",&m);
        for(i=0; i<26; i++)
        {
            node[i].left=NULL;
            node[i].right=NULL;
            node[i].value=0;
        }
        priority_queue<Node>q;
        cin>>ch;
        for(i=0; ch[i]!='\0'; i++)
        {
            node[ch[i]-'a'].value++;
        }
        for(i=0; i<26; i++)
            if(node[i].value)
                q.push(node[i]);
        /*
        while(!q.empty())
        {
            cout<<(q.top()).value<<endl;
            q.pop();
        }
        */
        while(q.size()>1)
        {
            tp1= new Node();
            *tp1=q.top();
            q.pop();
            if(!q.empty())
            {
                tp2= new Node();
                *tp2=q.top();
                q.pop();
                tp= new Node();
                tp->left=tp1;
                tp->right=tp2;
                tp->value=tp1->value+tp2->value;
                wpl+=tp->value;
                q.push(*tp);
            }
        }
        if(!q.empty())
        {
            head= new Node();
            *head=q.top();
            q.pop();
        }
        if(head&&head->left==NULL&&head->right==NULL)
        {
            wpl=head->value;
            wpl2=head->value;
        }
        else
            wpl2=WPL(head);
        //printf("%d\n",wpl);
        //printf("%d\n",wpl2);
        if(wpl<=m)//if(wpl2<=m)
            printf("yes\n");
        else
            printf("no\n");
    }
    return 0;
}

 

本題有兩個解法,一種是模擬構造haffuman樹,邊模擬邊計算wpl。這種解法其實不須要用結構體,數組就能夠,我只不過是爲了第二種方法才定義告終構體。node

第二種解法就是先構造好haffuman樹,而後再經過遍歷求得wpl顯然第一種更簡單。ios

相關文章
相關標籤/搜索