目录
问题:
4. |
【问题描述】 Julius Caesar 生活在充满危险和阴谋的年代。为了生存,他首次发明了密码,用于军队的消息传递。假设你是Caesar 军团中的一名军官,需要把Caesar 发送的消息破译出来、并提供给你的将军。消息加密的办法是:对消息原文中的每个字母,分别用该字母之后的第5个字母替换(例如:消息原文中的每个字母A都分别替换成字母F),其他字符不 变,并且消息原文的所有字母都是大写的。 密码字母:A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 原文字母:V W X Y Z A B C D E F G H I J K L M N O P Q R S T U 【输入形式】 最多不超过100个数据集组成。每个数据集由3部分组成: 起始行:START 密码消息:由1到200个字符组成一行,表示Caesar发出的一条消息 结束行:END 在最后一个数据集之后,是另一行:ENDOFINPUT 【输出形式】 每个数据集对应一行,是Caesar 的原始消息。 【样例输入】
【样例输出】
|
分析:
问题主要是如何将密码解密为原文?将密码的字母都换为之前第5位字母就ok,但是A B C D E需要额外注意,其对应V W X Y Z这五个字母。另外还有空格,标点符号不用处理。最后就是用什么数据结构存储信息了,我这里使用string字符串存储。
C++代码:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string caeserPwd; //凯撒密码字符串
string abcde = "VWXYZ"; //置换ABCDE使用字符串
string over; //获取END字符串专用
int len = 0; //存储凯撒密码长度
while(1) //直到输入ENDOFINPUT结束循环
{
getline(cin,caeserPwd); //获取一行密码,注意要使用getline()
if("START" == caeserPwd) //如果是起始行标志则执行下列代码
{
getline(cin,caeserPwd); //获取第二行密码,这一行就是密码体了。
len = caeserPwd.length(); //计算出密码长度
for(int i=0; i<len; i++)
{
if(caeserPwd[i] >= 'A' && caeserPwd[i] <= 'E') //如果是A-E之间的则置换为VWXYZ
caeserPwd[i] = abcde[caeserPwd[i] - 'A'];
else if(caeserPwd[i] >'E' && caeserPwd[i] <='Z') //如果是E-Z之间的字母则直接置换为其前边第五个字母
caeserPwd[i] = caeserPwd[i] - 5;
}
getline(cin,over); //获取密码结束行字符串
if("END" == over) //如果是END结束标志,则输出密码原文
cout << caeserPwd << endl;
}else if("ENDOFINPUT" == caeserPwd) //如果是结束输入标志ENDOFINPUT则结束程序
{
break;
}
}
return 0;
}
总结:
在CCF-CSP中一般第三题为字符串处理题目,而且是非常复杂的处理,所以最好使用string类来处理,string类提供了非常多而且非常方便的处理字符串函数。要注意的一点是一定要使用getline()函数获取字符串,不能使用cin。这两个的区别就是cin>>会自动过滤掉不可见字符(如空格 回车 tab等),遇到空格、回车等会结束获取输入的字符串,后面的字符串会过滤掉(存放在输入流中)。如果后面还需要输入字符串,则会从前面存放的字符串开始获取。而getline()属于string类的函数,使用时需包含头文件#include<string>。格式为:getline(cin,string s),接收一个字符串,可以接收空格、回车等,会获取整行内容。另一题也是,如果不使用getline()是拿不到满分的。字符串数字置换-CCF-CSP练习题(100)