CSU2080: 航行日志的修复

Description

作为CSU宇宙军事学院的全A优等生,你不负众望。在你的精确计算和指挥控制下,MACROSS凭借其主炮的强大威力,成功挫败了Zentraedi舰队一次又一次的进攻。指挥室和甲板上传来一阵又一阵的欢呼声,战事也渐趋平静。但就在格罗巴尔将军叼起了他爱用的烟斗,准备下达全舰修整的命令之时,MACROSS的背后突然产生了强烈的时空跳跃反应,大批飞弹迅猛飞来。幸好此刻洛伊·福克正率领统合军Skull大队在返回MACROSS的途中,成功阻拦了大部分飞弹,但还是有部分流弹击穿了装甲,控制室里传来急促的警报声。

此刻你正检查情报系统受损情况并执行修复任务。很幸运,并没有飞弹击穿情报室的装甲,但情报系统仍然出现了严重的紊乱情况,尤其是航行日志已经面目全非。由于航行日志记载着MACROSS战舰及其船员在航行过程中的各项情况,是舰队指挥官决策的一个重要依据,因此需要你立刻修复。

MACROSS的航行日志由自然语言记录,严格符合英文排版规范,每一行文本的末尾不会出现多余的空格。虽然除了英文字母外还可能会存在着标点符号和空格,但标点仅仅只有","和"."两种情形。经过和部分备份日志比对,你惊喜地发现情况并不是十分糟糕。尽管整体上字符的替换毫无规律,但对于英文字母来说,仅仅是向后移动固定位数的循环替换。然而这……似乎并没有多大帮助……

正当一筹莫展之时,一份英文字母频率表在你的眼前调皮的摆动。耳边随即传来那熟悉的银铃般的声音:“嘻嘻~这下你该怎么感谢我呀!”。

“咦,怎么是你?!”

The letter-frequency table on MACROSS

The letter-frequency table on MACROSS

Input

一份出现紊乱的航行日志文本。

Output

经过还原后的原始航行日志文本。

Sample Input

Xly`hld`mzcy`qcpp(`lyo`pgpcjhspcp`sp`td`ty`nsltyd}
Xlyj`l`zyp`mpwtpgpd`stxdpwq`esp`xldepc`zq`zespcd(
lyo`jpe`sp`td`l`rcplepc`dwlgp`esly`espj}
Szh`sld`estd`nslyrp`nzxp`lmzfe}`T`oz`yze`vyzh}
Hsle`nly`xlvp`te`wprtetxlep}`T`mpwtpgp`T`nly`dpeewp`estd`bfpdetzy}

Sample Output

Man was born free, and everywhere he is in chains.
Many a one believes himself the master of others,
and yet he is a greater slave than they.
How has this change come about. I do not know.
What can make it legitimate. I believe I can settle this question.


这题考到了两个点,第一个是字符串文本的读入,然后就是理解题意。思路:这题很简单,读入所有的字符之后找到出现频率最高的那个字母然后用e代替,其他的字母同样的向后移动固定位数的循环替换。

这题我在比赛的时候非常智障的用set去存储每一行的string,当时做的太着急了,然后忘了set会自动排序然后就导致乱码了。比赛结束换成queue就ac了。我个菜比。

附ac代码:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <sstream>
#include <set>
#include <queue>
using namespace std;
const int maxn = 1005;
string s;
int a[26];//a数组用来记录字母出现的个数,A和a视为同一个字母
int b[100005];//我觉得用字母还要区分大小写很麻烦,所以统一用数字0-25来代替字母A-Z与a—z,b数组就是来存储字符转化后的数字
queue<string>v;
char c3[100005];
char c1[26];//小写字母
char c2[26];//大写字母
int main()
{
	for (int i = 0; i<26; i++)
	{
		c1[i] = 'a' + i;
		c2[i] = 'A' + i;
	}
	string buf;
	int cnt1 = 0;
	while (cin>>s)
	{
		memset(a, 0, sizeof(a));
		int len = s.length();
		//cout<<len<<endl;
		for (int i = 0; i<len; i++)//将字符转换为数字,并记录个数
		{
			if (s[i] >= 'A'&&s[i] <= 'Z')
			{
				a[s[i] - 'A']++;
				b[cnt1++] = s[i] - 'A';
			}
			if (s[i] >= 'a'&&s[i] <= 'z')
			{
				a[s[i] - 'a']++;
				b[cnt1++] = s[i] - 'a';
			}
		}
		stringstream ss(s);//流用来读入文本
		while (ss >> buf)
		{
			v.push(buf);
		}
	}
	//cout<<v.size()<<endl;
	int max1 = 0;
	int flag;
	for (int i = 0; i<26; i++)
	{
		if (a[i]>max1)
		{
			max1 = a[i];
			flag = i;
		}
	}
	int cnt;
	cnt = 30 - flag;//找到频率最大的字母,并得到该字母转化成e循环移动了几位,
	for (int i = 0; i<cnt1; i++)
	{
		b[i] = (b[i] + cnt) % 26;
	}
	//cout<<cnt<<endl;
	int j = 0;
	while(!v.empty())//输出
	{
		string s1 = v.front();
		v.pop();
		//cout<<s1.length()<<endl;
		for (int i = 0; i<s1.length(); i++)
		{
			if (s1[i] >= 'A'&&s1[i] <= 'Z')
			{
				cout << c2[b[j++]];
			}
			if (s1[i] >= 'a'&&s1[i] <= 'z')
			{
				cout << c1[b[j++]];
			}
			if (s1[i] == '`')
				cout << " ";
			if (s1[i] == '(')
				cout << ",";
			if (s1[i] == '}')
				cout << ".";
		}
		cout << endl;
	}
	cout << endl;
	return 0;
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值