2
社区成员
发帖
与我相关
我的任务
分享P1906 凯撒密码
题目传送门
题目描述
在元老院的支持下,Caesar 率领罗马军团进攻高卢地区。但是他的军事行动并不顺利,他急需你的支持。
一天,你突然受到 Caesar 从前线写来的信。为了防止敌军偷窃情报,Caesar 决定用自创的密码来写这封信。但是面对满纸的乱码,你也无从下手。于是你前往元老院询问这种密码的玄机。
元老们告诉你,这是凯撒移位密码(世界上最早的加密术——编者注),解读它非常的简单:
对于明文中的每个字母,Caesar 会用它后面的第 t tt 个字母代替。例如,当 t = 2 t=2t=2 时,字母 A 将变成 C,字母 B 将变成 D,……,字母 Y 将变成 A,字母 Z 将变成 B(假设字母表是循环的)。
这样一来:
(t = 2)
[Plain Text] 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
[Cipher] C D E F G H I J K L M N O P Q R S T U V W X Y Z A B
[Plain Text] I Need Soldiers
[Cipher] K Pggf Uqnfkgtu
AI构建项目
plain
1
2
3
4
5
6
7
如此一来,需要传达的信息在外人看来就如同天书了。加上 Caesar 会不时更换 t tt 的值,使得密码变得更加难以捉摸。
你的任务是将 Caesar 的密码翻译为明文。
输入格式
你将得到若干段 Caesar 的密码,我们保证这是一句成文的英文句子。输入文件将保证小于 50 KB。
每个句子以一行 START 开始,下一行描述这个句子,再下一行以 END 结束。整个输入文件以 ENDOFINPUT 结束。
输出格式
对于每个句子,输出翻译后的明文。
输出请全部转为大写!
输入输出样例 #1
输入 #1
START
NS BFW, JAJSYX TK NRUTWYFSHJ FWJ YMJ WJXZQY TK YWNANFQ HFZXJX
END
START
N BTZQI WFYMJW GJ KNWXY NS F QNYYQJ NGJWNFS ANQQFLJ YMFS XJHTSI NS WTRJ
END
START
IFSLJW PSTBX KZQQ BJQQ YMFY HFJXFW NX RTWJ IFSLJWTZX YMFS MJ
END
ENDOFINPUT
AI构建项目
1
2
3
4
5
6
7
8
9
10
输出 #1
IN WAR, EVENTS OF IMPORTANCE ARE THE RESULT OF TRIVIAL CAUSES
I WOULD RATHER BE FIRST IN A LITTLE IBERIAN VILLAGE THAN SECOND IN ROME
DANGER KNOWS FULL WELL THAT CAESAR IS MORE DANGEROUS THAN HE
AI构建项目
1
2
3
说明/提示
如果你有看过《福尔摩斯探案集》的话,请回忆“跳舞娃娃”密码破译第一步;
我想这些可能会对你有帮助:
e 0.1268
t 0.0978
a 0.0788
o 0.0766
i 0.0707
n 0.0706
s 0.0634
r 0.0594
AI构建项目
plain
1
2
3
4
5
6
7
8
提示:
根据大量统计,在成文的英文句子中,字母 E 的出现频率最高。
你需要根据这一特性确定 t tt 的值。
数据保证这一特性可以唯一确定 t tt 的值。
解题思路
我搞了一晚上,搞出来了…
这道题有一些细节问题
1.转化大小写问题
输出格式后面有加黑的字
输出请全部转为大写!
我了解到不转大写是只有20分
2.t的问题
这道题,只要将字符按二十六个字母,向前t tt位
问题是,t是多少
他给了一张表
(t = 2)
[Plain Text] 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
[Cipher] C D E F G H I J K L M N O P Q R S T U V W X Y Z A B
[Plain Text] I Need Soldiers
[Cipher] K Pggf Uqnfkgtu
AI构建项目
plain
1
2
3
4
5
6
7
他把大家都以为是2,如何求t tt?看到提示,有一句话
根据大量统计,在成文的英文句子中,字母 E 的出现频率最高。
所以,我们找出出现最多的字母,它就是E的密文字母,相减就是t
3.输入输出输出问题
最后呢,就是这道题的输入要稍微注意一下
可能你们都知道cin后用getline会把空格和回车读入
如果直接打回车,这个getline就结束,于是打两个
解决问题方法
1.大小写转换
if判断是否是小写字母,如果是,减32
for(int i=0;i<s.size();i++)
{
if(s[i]>='a'&&s[i]<='z')
s[i]-=32;
}
AI构建项目
cpp
运行
1
2
3
4
5
2.求t
for(int i=0;i<s.size();i++)
a[int (s[i])]++;
int maxn=0,j;
for(int i='A';i<='Z';i++)
{
if(a[i]>maxn)
{
maxn=a[i];
j=i;
}
}
int t='E'-j;
AI构建项目
cpp
运行
1
2
3
4
5
6
7
8
9
10
11
12
3.输入
while(cin>>s1,getline(cin,s),getline(cin,s),cin>>e)
AI构建项目
cpp
运行
1
4.转换
int len=s.size();
for(int i=0;i<len;i++)
{
if(s[i]>='A'&&s[i]<='Z')
{
s[i]+=t;
if(s[i]>'Z') s[i]-=26;
if(s[i]<'A') s[i]+=26;
}
}
AI构建项目
cpp
运行
1
2
3
4
5
6
7
8
9
10
AC代码
#include<bits/stdc++.h>
using namespace std;
int t=0;int a[300];string ans[50005];int cnt=0;
int main()
{
string s,s1,e;
while(cin>>s1,getline(cin,s),getline(cin,s),cin>>e)
{
for(int i=0;i<s.size();i++)
{
if(s[i]>='a'&&s[i]<='z')
s[i]-=32;
}
cnt++;
for(int i=0;i<s.size();i++)
a[int (s[i])]++;
int maxn=0,j;
for(int i='A';i<='Z';i++)
{
if(a[i]>maxn)
{
maxn=a[i];
j=i;
}
}
int t='E'-j;
int len=s.size();
for(int i=0;i<len;i++)
{
if(s[i]>='A'&&s[i]<='Z')
{
s[i]+=t;
if(s[i]>'Z') s[i]-=26;
if(s[i]<'A') s[i]+=26;
}
}
ans[cnt]=s;
}
for(int i=1;i<=cnt;i++)
{
cout<<ans[i]<<endl;
}
}
————————————————
版权声明:本文为CSDN博主「mjhcsp」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/2501_90415399/article/details/155580194