华为OD机试-篮球游戏(Java 2024 D卷 100分)

题目描述

幼儿园里有一个放倒的圆桶,它是一个线性结构 ( Q ),允许在桶的右边将篮球放入,可以在桶的左边和右边将篮球取出。每个篮球有单独的编号,老师可以连续放入一个或多个篮球,小朋友可以在桶左边或右边将篮球取出,当桶里只有一个篮球的情况下,必须从左边取出。

输入描述

  1. 第一行的数字作为老师依次放入的篮球编号;
  2. 第二行的数字作为要检查是否能够按照放入顺序取出的篮球编号;
    其中篮球编号用逗号进行分隔。

输出描述

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

示例

输入:

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

输出:

RLRRRLL

说明:

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

解题思路

这个问题可以通过模拟篮球的放入和取出过程来解决。我们可以使用一个双端队列(deque)来模拟圆桶的行为。具体步骤如下:

  1. 将老师放入的篮球编号依次加入队列的右边。
  2. 对于要检查的取出序列,依次尝试从队列的左边或右边取出篮球。
  3. 如果当前要取出的篮球编号与队列的左边或右边的篮球编号匹配,则记录取出方向,并将该篮球从队列中移除。
  4. 如果无法匹配,则输出"NO"。
  5. 如果所有篮球都能成功取出,则输出取出方向的序列。

代码实现

Java
import java.util.*;

public class Solution {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        // 读取输入的篮球编号
        String[] input = scanner.nextLine().split(",");
        // 读取要检查的取出序列
        String[] output = scanner.nextLine().split(",");
        
        // 使用双端队列模拟圆桶
        Deque<String> deque = new ArrayDeque<>();
        // 将输入的篮球编号依次加入队列的右边
        for (String ball : input) {
            deque.addLast(ball);
        }
        
        // 用于记录取出方向的序列
        StringBuilder result = new StringBuilder();
        // 遍历要检查的取出序列
        for (String ball : output) {
            // 如果队列不为空且队首的篮球编号匹配
            if (!deque.isEmpty() && deque.peekFirst().equals(ball)) {
                result.append("L"); // 记录从左取出
                deque.removeFirst(); // 移除队首的篮球
            } 
            // 如果队列不为空且队尾的篮球编号匹配
            else if (!deque.isEmpty() && deque.peekLast().equals(ball)) {
                result.append("R"); // 记录从右取出
                deque.removeLast(); // 移除队尾的篮球
            } 
            // 如果无法匹配,输出"NO"并结束程序
            else {
                System.out.println("NO");
                return;
            }
        }
        // 输出取出方向的序列
        System.out.println(result.toString());
    }
}
Python
from collections import deque

# 读取输入的篮球编号
input_balls = input().split(',')
# 读取要检查的取出序列
output_balls = input().split(',')

# 使用双端队列模拟圆桶
queue = deque(input_balls)
# 用于记录取出方向的序列
result = []

# 遍历要检查的取出序列
for ball in output_balls:
    # 如果队列不为空且队首的篮球编号匹配
    if queue and queue[0] == ball:
        result.append('L') # 记录从左取出
        queue.popleft() # 移除队首的篮球
    # 如果队列不为空且队尾的篮球编号匹配
    elif queue and queue[-1] == ball:
        result.append('R') # 记录从右取出
        queue.pop() # 移除队尾的篮球
    # 如果无法匹配,输出"NO"并结束程序
    else:
        print("NO")
        exit()

# 输出取出方向的序列
print(''.join(result))
C++
#include <iostream>
#include <deque>
#include <vector>
#include <sstream>

using namespace std;

int main() {
    string input, output;
    // 读取输入的篮球编号
    getline(cin, input);
    // 读取要检查的取出序列
    getline(cin, output);
    
    // 使用双端队列模拟圆桶
    deque<string> queue;
    stringstream ss(input);
    string ball;
    // 将输入的篮球编号依次加入队列的右边
    while (getline(ss, ball, ',')) {
        queue.push_back(ball);
    }
    
    stringstream ss2(output);
    string result;
    // 遍历要检查的取出序列
    while (getline(ss2, ball, ',')) {
        // 如果队列不为空且队首的篮球编号匹配
        if (!queue.empty() && queue.front() == ball) {
            result += 'L'; // 记录从左取出
            queue.pop_front(); // 移除队首的篮球
        } 
        // 如果队列不为空且队尾的篮球编号匹配
        else if (!queue.empty() && queue.back() == ball) {
            result += 'R'; // 记录从右取出
            queue.pop_back(); // 移除队尾的篮球
        } 
        // 如果无法匹配,输出"NO"并结束程序
        else {
            cout << "NO" << endl;
            return 0;
        }
    }
    // 输出取出方向的序列
    cout << result << endl;
    return 0;
}
JavaScript
const readline = require('readline');

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

let inputBalls, outputBalls;

// 读取输入的篮球编号和要检查的取出序列
rl.on('line', (line) => {
    if (!inputBalls) {
        inputBalls = line.split(',');
    } else {
        outputBalls = line.split(',');
        rl.close();
    }
}).on('close', () => {
    // 使用双端队列模拟圆桶
    const queue = [...inputBalls];
    // 用于记录取出方向的序列
    let result = '';

    // 遍历要检查的取出序列
    for (const ball of outputBalls) {
        // 如果队列不为空且队首的篮球编号匹配
        if (queue.length > 0 && queue[0] === ball) {
            result += 'L'; // 记录从左取出
            queue.shift(); // 移除队首的篮球
        } 
        // 如果队列不为空且队尾的篮球编号匹配
        else if (queue.length > 0 && queue[queue.length - 1] === ball) {
            result += 'R'; // 记录从右取出
            queue.pop(); // 移除队尾的篮球
        } 
        // 如果无法匹配,输出"NO"并结束程序
        else {
            console.log("NO");
            return;
        }
    }
    // 输出取出方向的序列
    console.log(result);
});

复杂度分析

  • 时间复杂度: O(n),其中 n 是篮球的数量。每个篮球最多被放入和取出一次。
  • 空间复杂度: O(n),用于存储篮球的队列。

总结

这个问题通过模拟篮球的放入和取出过程,使用双端队列来高效地解决问题。通过检查每个篮球的取出方向,可以确定是否能够按照给定的顺序取出篮球。

华为OD-B代表团坐车Java实现如下: 可以使用Java中的对象和类来实现代表团坐车的功能。 首先,我们可以创建一个代表团类(DelegateGroup),用于存储代表团中每个成员的姓名、目的地和乘车状态等信息。在代表团类中可以定义成员变量name、destination和status等,并添加相应的getter和setter方法。 然后,我们可以创建一个乘车类(Bus),表示可以坐的公共交通工具。在乘车类中可以定义一个成员变量capacity,表示公共交通工具的总容量,以及一个成员变量occupied,表示当前已经被占用的座位数量。同样,还可以添加getter和setter方法。 接下来,在主程序中,我们可以实例化几个代表团对象,例如通过DelegateGroup类创建代表团成员A、B、C等,并为每个成员指定目的地和乘车状态等信息。 然后,我们可以实例化一个公共交通工具对象,例如通过Bus类创建一个公交车对象bus,并设置总容量和当前已被占用的座位数量等信息。 接着,我们可以通过循环遍历代表团成员,根据成员的乘车状态来判断是否可以为该成员配座位。如果成员的乘车状态为“需要乘车”且公共交通工具的座位尚未全部被占用,那么可以为该成员配一个座位,并将公共交通工具的已占用座位数量加1。如果成员的乘车状态为“不需要乘车”或公共交通工具的座位已全部占满,那么不为该成员配座位。 最后,我们可以输出每个代表团成员的姓名、目的地和乘车状态,并输出公共交通工具的总容量和已占用座位数量等信息。 以上就是用Java实现代表团坐车功能的简单示例。还可以根据实际需求进行扩展和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

蓝白咖啡

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

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

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

打赏作者

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

抵扣说明:

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

余额充值