笔试算法题(二)

题目描述

李雷和韩梅梅坐前后排。上课想说话怕老师发现,所以改为传小纸条。为了被老师发现他们纸条上说的是啥,他们约定了如下方法传递信息:
将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

解题思路:

  1. 根据输入的日期,将字符串循环变化出最终的三个字符串
  2. 根据传递字符串挨个字符进行查找(有点暴力…我认为这一步开始可以优化更好的方法)
  3. 先定位到组号,再定位到组内序号,直接输出

代码实现(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;
}

以上就是一次真实的笔试题分享,希望有更好的思路或者不足之处欢迎在评论区指出,共同进步,谢谢

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章