P1906 凯撒密码 题解
开始看到这道题,好迷茫
偏移量是什么呢?
题目说明更是让我疑惑不已
问了度娘才知道
第二条说明是英语构词中,字母出现频率的一个排行榜
("e"在英语单词中出现频率最高)
那么题目的意思就是:
把第一句暗文中出现最多的字母翻译为"e(E)",求出偏移量t
这样一来题目就简单了
我的代码思路呢,就是将问题分解,用自定义函数解决小问题
那么这道题就需要
①输入
②求t
③翻译
④储存
⑤输出
但还需要注意的是
所以可以先写下这段代码
void change(string &s)//将小写转为大写
{
int i;
int len=s.size();
for(i=0;i<len;i++)
{
if(s[i]>='a'&&s[i]<='z')
s[i]-=32;
}
}
这段代码也不难写
void translate(string &s,int t)//假设已知t,传址翻译暗文
{
int len=s.size();
for(int i=0;i<len;i++)
{
if(s[i]>='A'&&s[i]<='Z')
{
s[i]+=t;//有左移和右移两种移法,那t就有正负两种情况
if(s[i]>'Z') s[i]-=26;
if(s[i]<'A') s[i]+=26;//所以这里要有两个边界判断
}
}
}
然后就是
求出t
int f(string s)
{
int i,len=s.size();
for(i=0;i<len;i++)
v[(int)s[i]]++;
int maxn=0,j;
for(i='A';i<='Z';i++)
{
if(v[i]>maxn)
{
maxn=v[i];
j=i;
}
}
int ans='E'-j;//"E"是翻译成的明文,求偏移量用"E"-某出现最多字母
return ans;
}
最后呢,就是这道题的输入要稍微注意一下(嗯、当然是用"while(cin>>...)")
表示苯蒟蒻在这里卡了很久
可能你们都知道cin后用getline会把空格和回车读入
如果直接打回车,这个getline就结束了(做了这道题后我才知道)
所以要打两个getline
那代码就是这样
#include<bits/stdc++.h>
using namespace std;
string a,s,e,ans[50];
int num,v[150],t;
void change(string &s)//将小写转为大写
{
int i;
int len=s.size();
for(i=0;i<len;i++)
{
if(s[i]>='a'&&s[i]<='z')
s[i]-=32;
}
}
void translate(string &s,int t)
{
int len=s.size();
for(int i=0;i<len;i++)
{
if(s[i]>='A'&&s[i]<='Z')
{
s[i]+=t;//有左移和右移两种移法,那t就有正负两种情况
if(s[i]>'Z') s[i]-=26;
if(s[i]<'A') s[i]+=26;//所以这里要有两个边界判断
}
}
}
int f(string s)
{
int i,len=s.size();
for(i=0;i<len;i++)
v[(int)s[i]]++;
int maxn=0,j;
for(i='A';i<='Z';i++)
{
if(v[i]>maxn)
{
maxn=v[i];
j=i;
}
}
int ans='E'-j;//"E"是翻译成的明文,求偏移量用"E"-某出现最多字母
return ans;
}
int main()
{
while(cin>>s,getline(cin,a),getline(cin,a),cin>>e)
{
change(a);
num++;
if(num==1)//t根据第一句话来求
t=f(a);
translate(a,t);
ans[num]=a;
}
for(int i=1;i<=num;i++)
cout<<ans[i]<<endl;
return 0;
}