题目描述
李雷和韩梅梅坐前后排。上课想说话怕老师发现,所以改为传小纸条。为了被老师发现他们纸条上说的是啥,他们约定了如下方法传递信息:
将26个英文字母(全为大写),外加空格,一共27个字符分成三组,每组9个。也就是ABCDEFGHI是第一组,JKLMNOPQR是第二组,STUVWXYZ是第三组(此处用代表空格)。
然后根据传递纸条那天的日期,改变字母的位置
先根据月份数m, 以整个分组为单位进行循环左移,移动(m-1)次。然后根据日期数d,对每个分组内的字符进行循环左移,移动(d-1)次。
例如:以3月8号为例,首先移动分组,3月需要循环左移2次,变成:STUVWXYZ*,ABCDEFGHI,JKLMNOPQR
然后对每组内的字符,8日需要循环左移7次,最终编程:
Z*STUVWXY,HIABCDEFG,QRJKLMNOP
对于需要传递信息中的每个字符。用组号和组内序号两个数字来表示。
如果在3月8号需要传递信息为“HAPPY”,那么H位于第2组第1个,A位于第2组第3个…依次类推。所以最终纸条上写成:
21 23 39 39 19
现给定日期和需要传递的信息,请输出应该写在纸条上的编码。
输入规范
每个输入包含两行。第一行是用空格分隔的两个数字,分别代表月份和日子。输入保证是一个合法的日期
第二行为需要编码的信息字符串,仅由大写字母A~Z和空格组成,字符串长度不超过1024个字符。
输出规范
对每个输入,打印对应的编码,数字之间用空格分隔,每个输出占一行。
输入示例1:
3 8
HAPPY
输出实例1:
21 23 39 39 19
输入示例2:
2 14
I LOVE YOU
输出实例2:
35 25 18 12 29 31 25 23 12 28
解题思路:
- 根据输入的日期,将字符串循环变化出最终的三个字符串
- 根据传递字符串挨个字符进行查找(有点暴力…我认为这一步开始可以优化更好的方法)
- 先定位到组号,再定位到组内序号,直接输出
代码实现(C++):
#include <bits/stdc++.h>
#include <string>
using namespace std;
int main(){
const string s[3] = {"ABCDEFGHI", "JKLMNOPQR", "STUVWXYZ*"};
int n,m;
cin>>n>>m;
//第一步 要变换出最终的三个字符串
int year = (n-1)%3;
int day = (m-1)%9;
string s1[3];
for(int i = 0; i < 3; i++){
s1[i] = "";
int count = year + i;
if(count >= 3){
count -= 3;
}
s1[i] = s[count].substr(day) + s[count].substr(0, day);
}
string str;
cin.get();
getline(cin, str);
//第二步 根据传递信息的字符串每个字符进行查询输出结果
//第二步实现没多想,很暴力,肯定有更优解
for(int i = 0; i < str.length(); i++){
for(int j = 0; j < 3; j++){ //定位组号
if((str[i] - s1[j][9-day] <= 8 && str[i] - s1[j][9-day] >= 0) || (s1[j][9-day] == 'S' && str[i] == ' ')){
cout<<j+1;
for(int k = 0; k < 9; k++){ //定位组内序号
if(str[i] == s1[j][k] || (str[i] == ' ' && s1[j][k] == '*')){
cout<<k+1<<' ';
break;
}
}
break;
}
}
}
return 0;
}
以上就是一次真实的笔试题分享,希望有更好的思路或者不足之处欢迎在评论区指出,共同进步,谢谢