首页 > 代码库 > HDU-2527 Safe Or Unsafe

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        else120          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          else134             cout<<"no"<<endl;135      }136      return 0;137 }

 

 

HDU-2527 Safe Or Unsafe