华为OD机试 - 转骰子(Python/JS/C/C++ 2024 E卷 100分)

在这里插入图片描述

华为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来实现。

  1. 定义立方体状态:使用一个长度为6的数组state来表示立方体的六个面,索引分别对应左、右、前、后、上、下。
  2. 实现旋转方法:定义一个通用的旋转方法rotate,用于交换立方体上四个面的值。每个具体的操作(L、R、F、B、A、C)将调用rotate方法,传入相应的面索引。
  3. 读取输入并执行操作:使用Scanner读取输入的操作序列,逐个执行对应的操作方法。
  4. 输出最终状态:按照左、右、前、后、上、下的顺序输出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在线答疑。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哪 吒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值