zoukankan      html  css  js  c++  java
  • HDU2527 Safe Or Unsafe(哈夫曼的一道简单题)

    如果想进一步了解哈夫曼树的话链接为:http://www.cnblogs.com/jiangjing/archive/2013/01/16/2862828.html

    题意:就是给你一个字符串如:12     helloworld统计出其中d:1个,e:1个,h:1个,l:3个,o:2个,r:1个,w:1个,然后用一个数组保存起来a[7]={1,1,1,1,1,2,3};然后就是用哈夫曼树的思想求出新建的非叶子节点的权值之和:sum与12相比较如果sum小于等于12的话就输出yes否则输出no,此案例求出的sum=27;所以输出no。

    思路:按照建立哈夫曼树的思路每次求出两个的权值用min1保存最小的,min2保存次小的,然后(min1+min2)加入其中,但是min1和min2需要踢出去,此题我用优先队列做的,就是每次弹出最小的(min1)和次小的(min2),然后把(min1+min2)压入队列中。

    但是有一组很坑爹的测试数据,开始的时候一直错,5 aaaaa 输出的是yes,5 aaaaaa输出的是no

    第一种方法(优先队列)代码实现:

    #include<iostream>
    #include<cstring>
    #include<queue>
    using namespace std;
    struct node{
        friend bool operator<(node n1,node n2)
        {
            return n1.t>n2.t;
        }
        int t;
    };
    char a[100001];
    int main()
    {
        int T,n,i,j,len,b[26],sum,cao;
        node temp;
        while(scanf("%d",&T)!=EOF)
        {
            while(T--)
            {
                sum=0;
                priority_queue<node>Q;
                len=0;
                memset(b,0,sizeof(b));
                scanf("%d",&n);
                getchar();
                scanf("%s",a);
                for(i=0;a[i]!='\0';i++)
                    b[a[i]-'a']++;
                for(i=0;i<26;i++)
                   if(b[i]!=0)
                   {
                       temp.t=b[i];
                       Q.push(temp);
                       len++;
                   }
                i=0;
                if(len==1)//坑爹的地方
                    sum=Q.top().t;
                else
                {
                  while(i<len-1)
                  {
                    sum+=Q.top().t;//最小的
                    cao=Q.top().t;
                    Q.pop();
                    sum+=Q.top().t;//次小的
                    cao+=Q.top().t;
                    Q.pop();
                    temp.t=cao;
                    Q.push(temp);//新形成的加入队列
                    i++;
                  }
                }
                if(sum<=n)
                    printf("yes\n");
                else
                    printf("no\n");
            }
        }
        return 0;
    }

     第二种方法(建立哈夫曼树的方法,有些步骤可以省的):

    #include<iostream>
    #include<cstring>
    using namespace std;
    struct node{
      int weight;
      int parent,left,right;
    };
    char a[100001];
    int nima(int str[],int size)
    {
       int i,lenth=2*size,min1,min2,x,y,sum=0,j;
       struct node *hf;
       hf=(struct node *)malloc(lenth*sizeof(struct node));
       for(i=size;i<lenth;i++)
       {
          hf[i].weight=str[i-size];
          hf[i].parent=hf[i].left=hf[i].right=0;
       }
       for(i=size-1;i>0;i--)
       {
           min1=min2=10000000;x=y=0;
           for(j=i+1;j<lenth;j++)
           {
               if(min1>hf[j].weight&&hf[j].parent==0)
               {
                   min2=min1;y=x;
                   min1=hf[j].weight;
                   x=j;
               }
               else if(min2>hf[j].weight&&hf[j].parent==0)
               {
                   y=j;
                   min2=hf[j].weight;
               }
           }
           hf[i].weight=min1+min2;
           sum=sum+hf[i].weight;
           hf[i].parent=0;
           if(x>y)
               swap(x,y);
           hf[i].left=y;
           hf[i].right=x;
           hf[x].parent=i;
           hf[y].parent=i;
       }
       return sum;
    }
    int main()
    {
        int T,n,i,j,len,num[26],b[26];
        while(scanf("%d",&T)!=EOF)
        {
            while(T--)
            {
               len=0;
               memset(b,0,sizeof(b));
               scanf("%d",&n);
               getchar();
               scanf("%s",a);
               for(i=0;a[i]!='\0';i++)
                   b[a[i]-'a']++;
               for(i=0;i<26;i++)
                   if(b[i]!=0)
                       num[len++]=b[i];
                   if(len==1)
                   {
                       if(num[0]<=n)
                         printf("yes\n");
                       else
                         printf("no\n");
                   } 
                   else
                   {
                       if(nima(num,len)<=n)
                          printf("yes\n");
                       else
                          printf("no\n");
                   }
            }
        }
        return 0;
    }
  • 相关阅读:
    谈谈入职新公司1月的体会
    来点高逼格的,使用前端Sendmessage实现SSO
    2019做的第一个艰难决定
    Golang中设置函数默认参数的优雅实现
    linux系统shell基础知识入门二
    在AWS中自定义Credential Provider实现Client连接
    linux系统shell基础知识入门
    初学者学习golang可能遇到的坑
    【Menu】 目录索引
    rsync 服务介绍及相关实验
  • 原文地址:https://www.cnblogs.com/jiangjing/p/2862657.html
Copyright © 2011-2022 走看看