第五届图灵杯1872PJ的情书

来源:互联网 发布:大数据监控系统 编辑:程序博客网 时间:2024/06/04 23:35

1872: PJ的情书

描述

题目描述:

寂寞的PJ终于找到了一个超级可爱的女朋友,他想给她写一封情书,但是他文笔不好,情商又低,只能写写代码才能维持的了生活这个样子 正好PJ可爱的女朋友也是学计算机的,她刚刚学完《计算机导论》,于是PJ灵机一动,打算用二进制写一封情书给她。 因为PJ凑不出来字数,于是PJ想到了这么一种编码方式来延长自己的情书长度: 1、先用英语写好情书,记录出现的英文字符的种类n(0<n<=52),区分大小写。 2、记录每种英文字符出现的频数,按从大到小的次序排好放入队列。如果频数相同,则按字典序。 3、将当前队列中的队首两元素分别作为左右子节点(频数较高的作为左子节点)创建一个父节点,父节点自身的频数值为左右节点的和。并将该父节点放回到队首。 4、重复上述行为直到队列中所有的元素都已经添加到同一棵二叉树上。 5、从根节点开始以深度优先的方式遍历节点,每个节点的左树枝边值记为0,右树枝边值记为1,直到叶节点,按顺序读取树枝的值便是我们所要的该字符的编码,我们称之为PJ编码。 值得注意的是,PJ希望他的情书可读性更强,所以他只转换英文字符,其他字符都不变。并且在输出情书正文之前他要先给他可爱的女孩一个字典以便读懂这篇情书。 情书的长度不超过600字符

输入:

以文件结尾为结束,输入一整篇英文情书,包括空格和回车。

输出:

前n行以从出现频数高到低输出已经出现的英文字符和它对应的PJ编码,以英文冒号和空格隔开。 接下来按原来的格式输出已经转换成PJ编码形式的情书。

样例输入
I AM PJ
I Love you so much!
CC
样例输出
o: 000000000000000
C: 000000000000001
I: 00000000000001
u: 0000000000001
A: 000000000001
J: 00000000001
L: 0000000001
M: 000000001
P: 00000001
c: 0000001
e: 000001
h: 00001
m: 0001
s: 001
v: 01
y: 1
00000000000001 000000000001000000001 0000000100000000001
00000000000001 000000000100000000000000001000001 10000000000000000000000000001 001000000000000000 00010000000000001000000100001!
000000000000001000000000000001
水一波水一波~~~~
这道题不必使用优先队列,它和哈夫曼有些区别,权值小的在前,大的在后
就是哈夫曼的改编版~~~~
当然啦,,这道题还可以偷懒~~~~
其实是可以强解的,有规律,类似模拟了。
贴代码:
#include<bits/stdc++.h>using namespace std;int value[52];struct pj{char c;int v;string s;}a[52];struct cmp{bool operator()(const pj &a1,const pj&a2){if(a1.v != a2.v)return a1.v > a2.v;elsereturn a1.c < a2.c;}};int main(){string s;char cc;while((cc = getchar()) !=EOF){s += cc;}for(int i=0;i<s.size();i++){if(s[i] >= 'a' && s[i] <= 'z')value[s[i]-'a'] ++;if(s[i] >= 'A' && s[i] <= 'Z')value[s[i]-'A'+26] ++;}int cnt=0;for(int i=0;i<52;i++){if(i < 26 && value[i] != 0){a[cnt].c = 'a' + i;a[cnt].v = value[i];cnt ++;}if(i >= 26 && value[i] != 0){a[cnt].c = 'A' + i - 26;a[cnt].v = value[i];cnt ++;}}sort(a,a+cnt,cmp());char str1 = '0',str2 = '1';for(int i=1;i<=cnt-1;i++)a[0].s += str1;for(int i=1;i<cnt;i++){for(int j=cnt-1-i;j>=1;j--)a[i].s += str1;a[i].s += str2;}for(int i =0;i<cnt;i++){cout<<a[i].c<<": "<<a[i].s<<endl;}map<char,string>mp;for(int i=0;i<cnt;i++)mp[a[i].c] = a[i].s;map<char,string>::iterator it;for(int i=0;i<s.size();i++){if(s[i] >='a' && s[i] <= 'z' || s[i] >= 'A' && s[i] <= 'Z'){it = mp.find(s[i]);cout<<it->second;}elsecout<<s[i];}return 0;}


原创粉丝点击