HDU2527 Safe Or Unsafe 哈夫曼树

本题链接:http://acm.hdu.edu.cn/showproblem.php?pid=2527

此题考查的是哈夫曼树,构造哈夫曼树并计算出最小编码数即可。

做此题的过程中,提交之后竟然TLE,很是郁闷,找了几遍,还是没找出错误,可以肯定算法是不会错的,这方面不会超时,当测试只有一个字符的时候,发现问题了,出现了死循环,因为当只有1个或一种相同的字符的时候,并没有进行构造哈弗曼数的过程,因此在下面的找最小编码数的时候,出现了死循环,这个地方需要特殊计算最小编码数。改过之后,立刻就AC了,真是感慨,不过还挺满意的,自己构造出了哈夫曼树,继续加油!\(^o^)/~

AC代码如下:

#include<iostream>
using namespace std;
#include<string.h>
struct node
{
    int r,l,p,data;
}ha[100];
char s[100000];
int main()
{
    //freopen("d:\\1.txt","r",stdin);
    int n,a[27],b[27],c[27];
    cin>>n;
    while(n--)
    {
        int m1,h,s1=0;
        int i,j,k=0;    
        cin>>m1;
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        memset(c,0,sizeof(c));
        scanf("%s",s);
        int l=strlen(s);        
        for(i=0;i<l;i++)
        {
            int m=s[i]-96;
            a[m]++;
        }
        for(i=1;i<=26;i++)
        {
            if(a[i])
            b[++k]=a[i];
        }
        if(k!=1)//特别注意要考虑k=1的情况,因为没有进行构成哈夫曼树的操作,所以将会在下面出现死循环
        {
        //构造哈夫曼树
        memset(ha,0,sizeof(ha));
        for(i=1;i<=k;i++)
         ha[i].data=b[i];
        for(i=1;i<k;i++)//共有k-1个结点需要补充
        {
            int max=10000000;    
            int m1,m2,x1,x2;
            m1=max;//m2存上一个m1的值,m1存最新的值,x2存上一个x1的值,x1存最新的值
            m2=max;//m1,m2存结点的权值,x1,x2分别存结点的左右孩子的位置
            x1=0;
            x2=0;
            for(j=1;j<k+i;j++)
            {
                if(ha[j].data<m1&&ha[j].p==0)
                {
                    m2=m1;
                    m1=ha[j].data;
                    x2=x1;
                    x1=j;
                }
                else if(ha[j].data<m2&&ha[j].p==0)
                {
                    m2=ha[j].data;
                    x2=j;
                }
            }
            ha[k+i].l=x1;
            ha[k+i].r=x2;
            ha[x1].p=k+i;
            ha[x2].p=k+i;
            ha[k+i].data=ha[x1].data+ha[x2].data;
        } 
        //测试输出树
        /*for(i=1;i<2*k;i++)
        {
            cout<<i<<' '<<ha[i].l<<' '<<ha[i].data<<' '<<ha[i].r<<' '<<ha[i].p<<endl;
        }*/
        //求最小编码数
        for(i=1;i<=k;i++)
        {
            j=i;
            for(;;)
            {
                h=ha[j].p;
                j=h;
                c[i]++;
                if(h==2*k-1)break;//若不讨论 将会在此死循环 因为h会恒等于0
            }
            s1+=b[i]*c[i];
        }
        }
        else 
        s1=b[1]*1;
        //cout<<"s1="<<s1<<endl;
        
        if(s1<=m1)cout<<"yes"<<endl;
        else cout<<"no"<<endl;
            
    }
    return 0;
}

 

 

posted @ 2012-05-05 00:30  龙杉老师  阅读(650)  评论(0编辑  收藏  举报