华为OD机试真题 - 篮球游戏 - 双端队列(Python/JS/C/C++ 2024 D卷 100分)

在这里插入图片描述

华为OD机试 2024E卷题库疯狂收录中,刷题点这里

专栏导读

本专栏收录于《华为OD机试真题(Python/JS/C/C++)》

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。

一、题目描述

幼儿园里有一个放倒的圆桶,它是一个线性结构,允许在桶的右边将篮球放入,可以在桶的左边和右边将篮球取出。

每个篮球有单独的编号,老师可以连续放入 一个或多个篮球,小朋友可以在桶左边或右边将篮球取出,当桶里只有一个篮球的情况下,必须从左边取出。

如老师按顺序放入1、2、3、4、5 共5个编号的篮球,那么小朋友可以依次取出的编号为“1,2,3,4,5”或者“3,1,2,4,5”编号的篮球,无法取出 “5,1,3,2,4” 编号的篮球。

其中“3,1,2,4,5”的取出场景为:

连续放入1,2,3号

从右边取出3号

从左边取出1号

从左边取出2号

放入4号

从左边取出4号

放入5号

从左边取出5号

简单起见,我们以L表示左,R表示右,此时的篮球的依次取出序列为“ RLLLL ”

二、输入描述

1、第一行的数字作为老师依次放入的篮球编号;

2、第二行的数字作为要检查是否能够按照放入顺序取出的篮球编号;

其中篮球编号用逗号进行分隔。

三、输出描述

对于每个篮球的取出序列,如果确实可以获取,请打印出其按照左右方向的操作的取出顺序,如果无法获取则打印"NO" 。

补充说明:

1<=篮球的编号,篮球个数<=200;

篮球上的数字不重复;

输出的结果中LR的必须为大写;

四、测试用例

测试用例1

1、输入

4,5,6,7,0,1,2
6,4,0,1,2,5,7

2、输出

RLRRRLL

3、说明

篮球的取出顺序依次为 “右,左,右,右,右,左,左”

测试用例2

1、输入

4,5,6,7,0,1,2
6,4,0,1,2,5,7

2、输出

RLRRRLL

3、说明

篮球的取出顺序依次为 “右,左,右,右,右,左,左”

五、解题思路

为了实现这个功能,我们需要模拟一个双端队列来处理篮球的放入和取出操作,并根据输入序列生成相应的取出序列。如果无法按照给定顺序取出篮球,则输出“NO”。

  1. 输入解析:
    • 读取老师依次放入的篮球编号。
    • 读取小朋友要检查的取出顺序。
  2. 模拟操作:
    • 使用一个双端队列来模拟篮球桶的操作。
    • 遍历要检查的取出顺序,按顺序模拟取出操作,记录每次操作的方向(L或R)。
    • 每次取出后检查是否可以按照要求顺序进行操作,如果可以记录操作,否则返回“NO”。
  3. 输出结果:
    • 如果所有操作都能按顺序完成,输出记录的操作序列。
    • 如果无法完成,输出“NO”。

六、Python算法源码

from collections import deque

def get_order_sequence(put_in, take_out):
    deque_list = deque()
    operations = []
    put_index = 0  # 索引放入序列

    for ball in take_out:
        # 处理放入操作,直到当前取出球在队列中
        while ball not in deque_list and put_index < len(put_in):
            deque_list.append(put_in[put_index])
            put_index += 1

        # 检查是否可以从左边或右边取出
        if deque_list and deque_list[0] == ball:
            deque_list.popleft()
            operations.append("L")
        elif deque_list and deque_list[-1] == ball:
            deque_list.pop()
            operations.append("R")
        else:
            return "NO"

    return "".join(operations)

def main():
    # 读取输入的放入序列和检查的取出序列
    put_in_seq = input().split(",")
    take_out_seq = input().split(",")

    # 将字符串数组转换为整数数组
    put_in = list(map(int, put_in_seq))
    take_out = list(map(int, take_out_seq))

    # 模拟篮球桶的操作
    result = get_order_sequence(put_in, take_out)

    # 输出结果
    print(result)

if __name__ == "__main__":
    main()

七、JavaScript算法源码

function getOrderSequence(putIn, takeOut) {
    let deque = [];
    let operations = [];
    let putIndex = 0; // 索引放入序列

    for (let ball of takeOut) {
        // 处理放入操作,直到当前取出球在队列中
        while (!deque.includes(ball) && putIndex < putIn.length) {
            deque.push(putIn[putIndex++]);
        }

        // 检查是否可以从左边或右边取出
        if (deque.length > 0 && deque[0] === ball) {
            deque.shift();
            operations.push("L");
        } else if (deque.length > 0 && deque[deque.length - 1] === ball) {
            deque.pop();
            operations.push("R");
        } else {
            return "NO";
        }
    }

    return operations.join("");
}

function main() {
    // 读取输入的放入序列和检查的取出序列
    const putInSeq = prompt("请输入放入序列,用逗号分隔:").split(",");
    const takeOutSeq = prompt("请输入取出序列,用逗号分隔:").split(",");

    // 将字符串数组转换为整数数组
    const putIn = putInSeq.map(Number);
    const takeOut = takeOutSeq.map(Number);

    // 模拟篮球桶的操作
    const result = getOrderSequence(putIn, takeOut);

    // 输出结果
    console.log(result);
}

// 调用主函数
main();

八、C算法源码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_SIZE 100

// 模拟双端队列的结构体
typedef struct {
    int data[MAX_SIZE];
    int front;
    int rear;
} Deque;

// 初始化双端队列
void initDeque(Deque *deque) {
    deque->front = 0;
    deque->rear = -1;
}

// 向队列尾部添加元素
void addLast(Deque *deque, int value) {
    if (deque->rear < MAX_SIZE - 1) {
        deque->data[++(deque->rear)] = value;
    }
}

// 从队列头部移除元素
int removeFirst(Deque *deque) {
    if (deque->front <= deque->rear) {
        return deque->data[(deque->front)++];
    }
    return -1;
}

// 从队列尾部移除元素
int removeLast(Deque *deque) {
    if (deque->rear >= deque->front) {
        return deque->data[(deque->rear)--];
    }
    return -1;
}

// 获取队列头部元素
int getFirst(Deque *deque) {
    if (deque->front <= deque->rear) {
        return deque->data[deque->front];
    }
    return -1;
}

// 获取队列尾部元素
int getLast(Deque *deque) {
    if (deque->rear >= deque->front) {
        return deque->data[deque->rear];
    }
    return -1;
}

// 检查队列中是否包含指定元素
int contains(Deque *deque, int value) {
    for (int i = deque->front; i <= deque->rear; i++) {
        if (deque->data[i] == value) {
            return 1;
        }
    }
    return 0;
}

char* getOrderSequence(int* putIn, int* takeOut, int n) {
    static char operations[MAX_SIZE];
    Deque deque;
    int putIndex = 0;
    int opIndex = 0;

    initDeque(&deque);

    for (int i = 0; i < n; i++) {
        int ball = takeOut[i];

        // 处理放入操作,直到当前取出球在队列中
        while (!contains(&deque, ball) && putIndex < n) {
            addLast(&deque, putIn[putIndex++]);
        }

        // 检查是否可以从左边或右边取出
        if (getFirst(&deque) == ball) {
            removeFirst(&deque);
            operations[opIndex++] = 'L';
        } else if (getLast(&deque) == ball) {
            removeLast(&deque);
            operations[opIndex++] = 'R';
        } else {
            return "NO";
        }
    }

    operations[opIndex] = '\0';  // 添加字符串结束符
    return operations;
}

int main() {
    int n;
    char putInStr[MAX_SIZE];
    char takeOutStr[MAX_SIZE];
    
    // 读取输入的放入序列和检查的取出序列
    printf("请输入放入序列,用逗号分隔: ");
    scanf("%s", putInStr);
    printf("请输入取出序列,用逗号分隔: ");
    scanf("%s", takeOutStr);

    // 将字符串数组转换为整数数组
    int putIn[MAX_SIZE], takeOut[MAX_SIZE];
    char *token;

    n = 0;
    token = strtok(putInStr, ",");
    while (token != NULL) {
        putIn[n++] = atoi(token);
        token = strtok(NULL, ",");
    }

    int m = 0;
    token = strtok(takeOutStr, ",");
    while (token != NULL) {
        takeOut[m++] = atoi(token);
        token = strtok(NULL, ",");
    }

    // 模拟篮球桶的操作
    char *result = getOrderSequence(putIn, takeOut, n);

    // 输出结果
    printf("%s\n", result);

    return 0;
}

九、C++算法源码

#include <iostream>
#include <sstream>
#include <deque>
#include <vector>
#include <string>

using namespace std;

string getOrderSequence(const vector<int>& putIn, const vector<int>& takeOut) {
    deque<int> dequeList;
    string operations;
    int putIndex = 0; // 索引放入序列

    for (int ball : takeOut) {
        // 处理放入操作,直到当前取出球在队列中
        while (find(dequeList.begin(), dequeList.end(), ball) == dequeList.end() && putIndex < putIn.size()) {
            dequeList.push_back(putIn[putIndex++]);
        }

        // 检查是否可以从左边或右边取出
        if (!dequeList.empty() && dequeList.front() == ball) {
            dequeList.pop_front();
            operations += "L";
        } else if (!dequeList.empty() && dequeList.back() == ball) {
            dequeList.pop_back();
            operations += "R";
        } else {
            return "NO";
        }
    }

    return operations;
}

vector<int> parseInput(const string& input) {
    vector<int> result;
    stringstream ss(input);
    string token;
    while (getline(ss, token, ',')) {
        result.push_back(stoi(token));
    }
    return result;
}

int main() {
    string putInStr, takeOutStr;

    // 读取输入的放入序列和检查的取出序列
    cout << "请输入放入序列,用逗号分隔: ";
    getline(cin, putInStr);
    cout << "请输入取出序列,用逗号分隔: ";
    getline(cin, takeOutStr);

    // 将字符串数组转换为整数数组
    vector<int> putIn = parseInput(putInStr);
    vector<int> takeOut = parseInput(takeOutStr);

    // 模拟篮球桶的操作
    string result = getOrderSequence(putIn, takeOut);

    // 输出结果
    cout << result << endl;

    return 0;
}


🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2024 E卷 200分)

🏆本文收录于,华为OD机试真题(Python/JS/C/C++)

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。

在这里插入图片描述

  • 18
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

哪 吒

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

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

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

打赏作者

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

抵扣说明:

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

余额充值