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;

}

 

 

你可能感兴趣的:(unsafe)