zoukankan      html  css  js  c++  java
  • 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;
    }

     

  • 相关阅读:
    如果再回到从前 备忘录模式
    在NBA我需要翻译 适配器模式
    无尽加班何时休 状态模式
    Linux网络编程学习(六) ----- 管道(第四章)
    Linux网络编程学习(五) ----- 信号(第四章)
    Linux网络编程学习(四) -----守护进程的建立(第三章)
    Linux网络编程学习(三) ----- 进程控制实例(第三章)
    Linux网络编程学习(二) ----- 进程控制(第三章)
    Linux网络编程学习(一) ----- 概论和Linux模型(第一章第二章)
    Linux网络编程学习计划
  • 原文地址:https://www.cnblogs.com/hsqdboke/p/2483887.html
Copyright © 2011-2022 走看看