筆試算法題(二)

題目描述

李雷和韓梅梅坐前後排。上課想說話怕老師發現,所以改爲傳小紙條。爲了被老師發現他們紙條上說的是啥,他們約定了如下方法傳遞信息:
將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;
}

以上就是一次真實的筆試題分享,希望有更好的思路或者不足之處歡迎在評論區指出,共同進步,謝謝

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