您的位置:首页 > 其它

1009-J

2016-03-31 13:46 253 查看
此题与1003-D相同        

1.题目编号:1009-J

2.简单题意:哈弗曼树,输入字符串,包括26位英文字母跟下划线,根据权数求出最优树,用字符数乘以8位ASCLL,也就是字符串乘以8,通过每个字符的权乘以同一个字符出现的次数,最后一个输出便是二者相除。

3.解题思路形成过程:哈弗曼树,画最优树,例如AAAAABCD,A有5个,权数便是5,B、C、D的权数都是一。先是输入字符串,先是判断字符串大小,所有字符数乘以8输出,再找出每个字符的个数,即每个字符的权,用数组1-26下标表示,根据最优树,左边为1,右边为0,只要计算出字符在第几列,在第几列就用列数乘以权,所有字符都求出来相加,输出,用第一个输出数除以第二个输出数,保留一位小数。
4.感想:曾经老师曾说过,大学里数学跟英语最重要,离散老师也说过,离散跟编程有很大关系,现在算是体会 了,哈弗曼树是上学期的离散学的,做着道题的时候,还特意去将书找出来,翻到哈弗曼树,重新看了一遍,知识需要巩固,需要积累。
5.AC代码:
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;

int main()
{
string s;
int m1,m2;
int a,b;
int len,ha[35];

priority_queue<int,vector<int>,greater<int> >q;//从小到大
while(cin>>s&&s!="END")
{
while(!q.empty())
q.pop();
len=s.length();
m1=len<<3;
memset(ha,0,sizeof(ha));
for(int i=0; i<len; i++)
{
if(s[i]>='A'&&s[i]<='Z')
ha[s[i]-'A'+1]++;
else
ha[0]++;
}
for(int i=0; i<30; i++)
{
if(ha[i])
{
q.push(ha[i]);
}
}
m2 = q.size()==1?len:0;
while(q.size()>1)
{
a=q.top();
q.pop();
b=q.top();
q.pop();
m2+=a+b;
q.push(a+b);
}
printf("%d %d %.1f\n",m1,m2,m1*1.0/m2);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  acm 贪心算法