HDU-2527 Safe Or Unsafe

http://acm.hdu.edu.cn/showproblem.php?pid=2527

建哈夫曼树,哈夫曼编码,求wpl值。

Safe Or Unsafe

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1511    Accepted Submission(s): 594

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
  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 using namespace std;
  5 struct node
  6 {
  7     char ch;//节点值
  8     int weight;//权重
  9     int parent;//双亲节点
 10     int lchild,rchild;//孩子节点
 11 }ht[20020];
 12 struct Hcode
 13 {
 14     char cd[10010];//存入01编码的字符串。
 15     int start;//长度的开始。
 16 }hcd[10010];
 17 void creat(node ht[],char *c,int *w,int n)//建哈夫曼树。
 18 {
 19      int i,s1,s2,k,min1,min2;
 20     for(i=1;i<=n;i++)//初始化叶子节点
 21     {
 22         ht[i].ch=c[i-1];//字符。
 23         ht[i].weight=w[i-1];//权值
 24         ht[i].parent=ht[i].lchild=ht[i].rchild=0;//开始为0.
 25     }
 26    for(;i<2*n;i++)//树的节点一共为2*n-1个。
 27     {
 28       ht[i].parent=0;
 29       ht[i].lchild=0;
 30       ht[i].rchild=0;
 31     }
 32    for(i=n+1;i<2*n;i++)
 33     {
 34         min1 = min2 = 9999999;
 35         for(k=1;k<=i-1;k++)//求权值最小的2个权值。
 36              if(ht[k].parent == 0)
 37              {
 38                  if(ht[k].weight<min1)
 39                  {
 40                       min2 = min1;
 41                       s2= s1;
 42                       min1= ht[k].weight;
 43                       s1= k;
 44                   }
 45                   else if(ht[k].weight<min2)
 46                   {
 47                       min2 = ht[k].weight;
 48                       s2 = k;
 49                   }
 50             }
 51         
 52          ht[s1].parent=i;//建立节点。
 53         ht[s2].parent=i;
 54         ht[i].lchild=s1;
 55         ht[i].rchild=s2;
 56         ht[i].weight=ht[s1].weight+ht[s2].weight;
 57      
 58     }
 59   
 60 }
 61 void creatHcode(node ht[],Hcode hcd[],int n)//哈夫曼编码。
 62 {
 63     int i,f,c;
 64     Hcode hc;
 65     for(i=1;i<=n;i++)
 66     {
 67         hc.start=n;
 68         c=i;
 69         f=ht[i].parent;
 70         while(f!=0)
 71         {
 72             if(ht[f].lchild==c)
 73                 hc.cd[hc.start--]='0';
 74             else
 75                hc.cd[hc.start--]='1';
 76             c=f;
 77             f=ht[f].parent;
 78         }
 79         hc.start++;
 80         hcd[i]=hc;
 81     }
 82 }
 83 int main()
 84 {
 85   int T,m,i,r,j;
 86    int w[200];
 87   char str[200],c[200];
 88   scanf("%d",&T);
 89   while(T--)
 90   {
 91      memset(w,0,sizeof(w));
 92       scanf("%d",&m);
 93       getchar();
 94       scanf("%s",str);
 95      int len=strlen(str);
 96            r=0;
 97            c[r++]=str[0];
 98            w[0]=1;
 99       for(i=1;i<len;i++)
100       {
101          for(j=0;j<r;j++)
102             {
103                  if(c[j]==str[i])
104                    {
105                      w[j]=w[j]+1;
106                      break;
107                    }
108             }
109             if(j==r)
110                {  w[r]=1;
111                    c[r++]=str[i];
112                }
113        }
114      c[r]='\0';
115      if(r==1)
116      {
117       if(w[0]<=m)
118          cout<<"yes"<<endl;
119        else
120          cout<<"no"<<endl;
121         continue;
122      }
123      creat(ht,c,w,r);
124      creatHcode(ht,hcd,r);
125      int wpl=0;
126        for(i=1;i<=r;i++)
127        {
128           wpl+=(r-hcd[i].start+1)*ht[i].weight;
129         
130        }
131      if(wpl<=m)
132             cout<<"yes"<<endl;
133          else
134             cout<<"no"<<endl;
135      }
136      return 0;
137 }

 

 
posted @ 2014-09-28 22:44  疯狂的癫子  阅读(359)  评论(0编辑  收藏  举报