HDOJ2527(Safe Or Unsafe)

Safe Or Unsafe

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


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
 
  
#include <iostream>
#include 
<cstring>
using namespace std;

typedef 
struct 
ExpandedBlockStart.gifContractedBlock.gif
{
    
int weight;
    
int parent, lchild, rchild;
}
HTNode, *HuffmanTree;

int charCnt[28];
HTNode HT[
52];
int result, m;

void init()
ExpandedBlockStart.gifContractedBlock.gif
{
    
for(int i = 0; i < 26; i++)
        charCnt[i] 
= 0;
}


void traverse(int root, int height)
ExpandedBlockStart.gifContractedBlock.gif
{
    
if(root)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        
if(HT[root].lchild)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            traverse(HT[root].lchild, height 
+ 1);
            
            traverse(HT[root].rchild, height 
+ 1);
        }

        
else
            result 
+= HT[root].weight * height;
    }

}


int getmin(int tt)
ExpandedBlockStart.gifContractedBlock.gif
{
    
int rr, mw, j = 1;
    
while(HT[j].parent)
        j
++;
    rr 
= j; mw = HT[j].weight;
    
for(j++; j <= tt; j++)
        
if(HT[j].weight < mw && !HT[j].parent)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            rr 
= j;
            mw 
= HT[j].weight;
        }

    HT[rr].parent 
= 1;
    
return rr;
}


void selectTwoMin(int tt, int &s1, int &s2)
ExpandedBlockStart.gifContractedBlock.gif
{
    
int kk;
    s1 
= getmin(tt);
    s2 
= getmin(tt);
    
if(s1 > s2)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        kk 
= s1;
        s1 
= s2;
        s2 
= kk;
    }

}


int HuffmanCoding()
ExpandedBlockStart.gifContractedBlock.gif
{
    
int i;
    
int mm, min1, min2;
    
int cc = 1;//stand for the total count of leaf
    for(i = 0; i < 26; i++)
        
if(charCnt[i])//节点0为空
ExpandedSubBlockStart.gifContractedSubBlock.gif
        {
            HT[cc].weight 
= charCnt[i];
            HT[cc].parent 
= HT[cc].lchild = HT[cc].rchild = 0;
            cc
++;
        }

    cc
--;
    
if(cc == 1)
        
return 1;
    mm 
= 2 * cc;
    
for(i = cc + 1; i < mm; i++)
        HT[i].parent 
= 0;
    
for(i = cc + 1; i < mm; i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        selectTwoMin(i 
- 1, min1, min2);
        
//cout<<min1<<"  "<<min2<<endl;
        HT[min1].parent = HT[min2].parent = i;
        HT[i].lchild 
= min1;
        HT[i].rchild 
= min2;
        HT[i].weight 
= HT[min1].weight + HT[min2].weight;
    }

    result 
= 0;
    traverse(mm 
- 10);
    
//cout<<"result:"<<result<<endl;
    if(result > m)
        cout
<<"no"<<endl;
    
else
        cout
<<"yes"<<endl;
    
return 0;
}


int main()
ExpandedBlockStart.gifContractedBlock.gif
{
    
char str[1000];
    
int n, i;
    
while(cin>>n)
        
while(n-- && cin>>m)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            cin
>>str;
            init();
            
for(i = 0; i < strlen(str); i++)
                charCnt[str[i] 
- 'a']++;
            
if(HuffmanCoding())
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
if(strlen(str) > m)
                    cout
<<"no"<<endl;
                
else
                    cout
<<"yes"<<endl;
            }

        }

    
return 0;
}

转载于:https://www.cnblogs.com/Xredman/archive/2009/04/06/1430427.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值