华为OD机试 2024E卷题库疯狂收录中,刷题点这里
专栏导读
本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。
一、题目描述
假设有一个立方体,每个面有一个数字,初始为:前1,右2,前3(观察者方向),后4,上5,下6,用123456表示这个状态,放置在平面上。
- 可以向左翻转(用L表示向左翻转1次);
- 可以向右翻转(用R表示向右翻转1次);
- 可以向前翻转(用F表示向前翻转1次);
- 可以向后翻转(用B表示向后翻转1次);
- 可以以逆时针旋转(用A表示逆时针旋转90度);
- 可以以顺时针旋转(用C表示顺时针旋转90度)。
现在从123456这个初始状态开始,根据输入的动作/指令,计算得出最终的状态。
二、输入描述
输入一行,为只包含LRFBAC的字母序列,最大长度为50,字母可重复。
三、输出描述
输出最终状态。
四、测试用例
测试用例1:
1、输入
LR
2、输出
123456
3、说明
立方体先向左翻转,再向右翻转回去,最终还是恢复到初始状态123456。
测试用例2:
1、输入
FCR
2、输出
342156
3、说明
立方体先向前翻转,状态变为125643,然后顺时针旋转,状态变为651243,最后向右翻转,状态变为342156。
五、解题思路
模拟一个立方体在平面上的翻转和旋转操作。立方体有六个面,分别标记为左(Left)、右(Right)、前(Front)、后(Back)、上(Up)、下(Down),每个面上有一个数字。初始状态为123456,表示左1、右2、前3、后4、上5、下6。
每个操作(L、R、F、B、A、C)会改变立方体各面的数字位置。为了实现这一点,我们可以使用一个长度为6的数组state来表示立方体的六个面,索引分别对应左、右、前、后、上、下。每个操作对应一个特定的数组置换,通过预定义的旋转方法rotate来实现。
- 定义立方体状态:使用一个长度为6的数组state来表示立方体的六个面,索引分别对应左、右、前、后、上、下。
- 实现旋转方法:定义一个通用的旋转方法rotate,用于交换立方体上四个面的值。每个具体的操作(L、R、F、B、A、C)将调用rotate方法,传入相应的面索引。
- 读取输入并执行操作:使用Scanner读取输入的操作序列,逐个执行对应的操作方法。
- 输出最终状态:按照左、右、前、后、上、下的顺序输出state数组中的数字。
六、Python算法源码
import sys
def rotate(state, a, b, c, d):
"""
通用的旋转方法,用于交换立方体上四个面的值。
通过传入四个索引,按顺序交换这四个面的位置。
参数:
state (list): 当前立方体的六个面列表,依次表示 左、右、前、后、上、下。
a (int): 要交换的第一个面索引
b (int): 要交换的第二个面索引
c (int): 要交换的第三个面索引
d (int): 要交换的第四个面索引
"""
temp = state[a] # 临时保存第一个面的值
state[a] = state[b] # 第二个面的值赋给第一个面
state[b] = state[c] # 第三个面的值赋给第二个面
state[c] = state[d] # 第四个面的值赋给第三个面
state[d] = temp # 第一个面的值赋给第四个面
def turnL(state):
"""
向左翻转 (L):
将左 -> 上 -> 右 -> 下 -> 左
"""
rotate(state, 0, 4, 1, 5) # 左->上->右->下->左
def turnR(state):
"""
向右翻转 (R):
将左 -> 下 ->右 -> 上 -> 左
"""
rotate(state, 0, 5, 1, 4) # 左->下->右->上->左
def turnF(state):
"""
向前翻转 (F):
将前 -> 上 -> 后 -> 下 -> 前
"""
rotate(state, 2, 4, 3, 5) # 前->上->后->下->前
def turnB(state):
"""
向后翻转 (B):
将前 -> 下 -> 后 -> 上 -> 前
"""
rotate(state, 2, 5, 3, 4) # 前->下->后->上->前
def turnA(state):
"""
逆时针旋转 (A):
将左 -> 后 -> 右 -> 前 -> 左
"""
rotate(state, 0, 3, 1, 2) # 左->后->右->前->左
def turnC(state):
"""
顺时针旋转 (C):
将左 -> 前 -> 右 -> 后 -> 左
"""
rotate(state, 0, 2, 1, 3) # 左->前->右->后->左
def main():
# 读取用户输入的指令序列
s = sys.stdin.read().strip()
# 初始状态:左、右、前、后、上、下
state = [1, 2, 3, 4, 5, 6] # 左1,右2,前3,后4,上5,下6
# 遍历每一个指令字符,并执行相应的操作
for ch in s:
if ch == 'L':
turnL(state) # 执行左翻转
elif ch == 'R':
turnR(state) # 执行右翻转
elif ch == 'F':
turnF(state) # 执行前翻转
elif ch == 'B':
turnB(state) # 执行后翻转
elif ch == 'A':
turnA(state) # 执行逆时针旋转
elif ch == 'C':
turnC(state) # 执行顺时针旋转
# 忽略无效字符
# 输出最终立方体的六个面状态,按照左、右、前、后、上、下的顺序
print(''.join(map(str, state)))
if __name__ == "__main__":
main()
七、JavaScript算法源码
const readline = require('readline');
// 创建接口以读取标准输入
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
/**
* 通用的旋转方法,用于交换立方体上四个面的值。
* 通过传入四个索引,按顺序交换这四个面的位置。
*
* @param {number[]} state - 当前立方体的六个面数组,依次表示 左、右、前、后、上、下。
* @param {number} a - 要交换的第一个面索引
* @param {number} b - 要交换的第二个面索引
* @param {number} c - 要交换的第三个面索引
* @param {number} d - 要交换的第四个面索引
*/
function rotate(state, a, b, c, d) {
let temp = state[a]; // 临时保存第一个面的值
state[a] = state[b]; // 第二个面的值赋给第一个面
state[b] = state[c]; // 第三个面的值赋给第二个面
state[c] = state[d]; // 第四个面的值赋给第三个面
state[d] = temp; // 第一个面的值赋给第四个面
}
/**
* 向左翻转 (L):
* 将左 -> 上 -> 右 -> 下 -> 左
*/
function turnL(state) {
rotate(state, 0, 4, 1, 5); // 左->上->右->下->左
}
/**
* 向右翻转 (R):
* 将左 -> 下 ->右 -> 上 -> 左
*/
function turnR(state) {
rotate(state, 0, 5, 1, 4); // 左->下->右->上->左
}
/**
* 向前翻转 (F):
* 将前 -> 上 -> 后 -> 下 -> 前
*/
function turnF(state) {
rotate(state, 2, 4, 3, 5); // 前->上->后->下->前
}
/**
* 向后翻转 (B):
* 将前 -> 下 -> 后 -> 上 -> 前
*/
function turnB(state) {
rotate(state, 2, 5, 3, 4); // 前->下->后->上->前
}
/**
* 逆时针旋转 (A):
* 将左 -> 后 -> 右 -> 前 -> 左
*/
function turnA(state) {
rotate(state, 0, 3, 1, 2); // 左->后->右->前->左
}
/**
* 顺时针旋转 (C):
* 将左 -> 前 -> 右 -> 后 -> 左
*/
function turnC(state) {
rotate(state, 0, 2, 1, 3); // 左->前->右->后->左
}
rl.on('line', (input) => {
let s = input.trim(); // 读取输入并去除首尾空格
// 初始状态:左、右、前、后、上、下
let state = [1, 2, 3, 4, 5, 6]; // 左1,右2,前3,后4,上5,下6
// 遍历每一个指令字符,并执行相应的操作
for (let ch of s) {
switch(ch) {
case 'L':
turnL(state); // 执行左翻转
break;
case 'R':
turnR(state); // 执行右翻转
break;
case 'F':
turnF(state); // 执行前翻转
break;
case 'B':
turnB(state); // 执行后翻转
break;
case 'A':
turnA(state); // 执行逆时针旋转
break;
case 'C':
turnC(state); // 执行顺时针旋转
break;
// 忽略无效字符
}
}
// 输出最终立方体的六个面状态,按照左、右、前、后、上、下的顺序
console.log(state.join(''));
rl.close(); // 关闭接口
});
八、C算法源码
#include <stdio.h>
#include <string.h>
// 通用的旋转方法,用于交换立方体上四个面的值。
// 通过传入四个索引,按顺序交换这四个面的位置。
void rotate(int state[], int a, int b, int c, int d) {
int temp = state[a]; // 临时保存第一个面的值
state[a] = state[b]; // 第二个面的值赋给第一个面
state[b] = state[c]; // 第三个面的值赋给第二个面
state[c] = state[d]; // 第四个面的值赋给第三个面
state[d] = temp; // 第一个面的值赋给第四个面
}
// 向左翻转 (L):将左 -> 上 -> 右 -> 下 -> 左
void turnL(int state[]) {
rotate(state, 0, 4, 1, 5); // 左->上->右->下->左
}
// 向右翻转 (R):将左 -> 下 ->右 -> 上 -> 左
void turnR(int state[]) {
rotate(state, 0, 5, 1, 4); // 左->下->右->上->左
}
// 向前翻转 (F):将前 -> 上 -> 后 -> 下 -> 前
void turnF(int state[]) {
rotate(state, 2, 4, 3, 5); // 前->上->后->下->前
}
// 向后翻转 (B):将前 -> 下 -> 后 -> 上 -> 前
void turnB(int state[]) {
rotate(state, 2, 5, 3, 4); // 前->下->后->上->前
}
// 逆时针旋转 (A):将左 -> 后 -> 右 -> 前 -> 左
void turnA(int state[]) {
rotate(state, 0, 3, 1, 2); // 左->后->右->前->左
}
// 顺时针旋转 (C):将左 -> 前 -> 右 -> 后 -> 左
void turnC(int state[]) {
rotate(state, 0, 2, 1, 3); // 左->前->右->后->左
}
int main() {
char s[51]; // 定义最多50个字符的指令序列,加1为结束符
scanf("%s", s); // 读取输入的指令序列
// 初始状态:左、右、前、后、上、下
int state[6] = {1, 2, 3, 4, 5, 6}; // 左1,右2,前3,后4,上5,下6
// 遍历每一个指令字符,并执行相应的操作
for(int i = 0; i < strlen(s); i++) {
char ch = s[i];
switch(ch) {
case 'L':
turnL(state); // 执行左翻转
break;
case 'R':
turnR(state); // 执行右翻转
break;
case 'F':
turnF(state); // 执行前翻转
break;
case 'B':
turnB(state); // 执行后翻转
break;
case 'A':
turnA(state); // 执行逆时针旋转
break;
case 'C':
turnC(state); // 执行顺时针旋转
break;
// 忽略无效字符
default:
break;
}
}
// 输出最终立方体的六个面状态,按照左、右、前、后、上、下的顺序
for(int i = 0; i < 6; i++) {
printf("%d", state[i]);
}
return 0;
}
九、C++算法源码
#include <iostream>
#include <string>
using namespace std;
/**
* 通用的旋转方法,用于交换立方体上四个面的值。
* 通过传入四个索引,按顺序交换这四个面的位置。
*
* @param state 当前立方体的六个面数组,依次表示 左、右、前、后、上、下。
* @param a 要交换的第一个面索引
* @param b 要交换的第二个面索引
* @param c 要交换的第三个面索引
* @param d 要交换的第四个面索引
*/
void rotate(int state[], int a, int b, int c, int d) {
int temp = state[a]; // 临时保存第一个面的值
state[a] = state[b]; // 第二个面的值赋给第一个面
state[b] = state[c]; // 第三个面的值赋给第二个面
state[c] = state[d]; // 第四个面的值赋给第三个面
state[d] = temp; // 第一个面的值赋给第四个面
}
/**
* 向左翻转 (L):
* 将左 -> 上 -> 右 -> 下 -> 左
*/
void turnL(int state[]) {
rotate(state, 0, 4, 1, 5); // 左->上->右->下->左
}
/**
* 向右翻转 (R):
* 将左 -> 下 ->右 -> 上 -> 左
*/
void turnR(int state[]) {
rotate(state, 0, 5, 1, 4); // 左->下->右->上->左
}
/**
* 向前翻转 (F):
* 将前 -> 上 -> 后 -> 下 -> 前
*/
void turnF(int state[]) {
rotate(state, 2, 4, 3, 5); // 前->上->后->下->前
}
/**
* 向后翻转 (B):
* 将前 -> 下 -> 后 -> 上 -> 前
*/
void turnB(int state[]) {
rotate(state, 2, 5, 3, 4); // 前->下->后->上->前
}
/**
* 逆时针旋转 (A):
* 将左 -> 后 -> 右 -> 前 -> 左
*/
void turnA(int state[]) {
rotate(state, 0, 3, 1, 2); // 左->后->右->前->左
}
/**
* 顺时针旋转 (C):
* 将左 -> 前 -> 右 -> 后 -> 左
*/
void turnC(int state[]) {
rotate(state, 0, 2, 1, 3); // 左->前->右->后->左
}
int main(){
string s;
cin >> s; // 读取输入的指令序列
// 初始状态:左、右、前、后、上、下
int state[6] = {1, 2, 3, 4, 5, 6}; // 左1,右2,前3,后4,上5,下6
// 遍历每一个指令字符,并执行相应的操作
for(char ch : s){
switch(ch){
case 'L':
turnL(state); // 执行左翻转
break;
case 'R':
turnR(state); // 执行右翻转
break;
case 'F':
turnF(state); // 执行前翻转
break;
case 'B':
turnB(state); // 执行后翻转
break;
case 'A':
turnA(state); // 执行逆时针旋转
break;
case 'C':
turnC(state); // 执行顺时针旋转
break;
// 忽略无效字符
default:
break;
}
}
// 输出最终立方体的六个面状态,按照左、右、前、后、上、下的顺序
for(int i = 0; i < 6; i++){
cout << state[i];
}
return 0;
}
🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2024 E卷 200分)
🏆本文收录于,华为OD机试真题(Python/JS/C/C++)
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。