华为机考真题 -- 篮球游戏

题目描述:

幼儿园里有一个放倒的圆桶,它是一个线性结构,只能在桶的右边将放入篮球,但是可以在桶的左边或者右边将取出篮球。每个篮球有单独的编号,老师可以一次性放入一个或者多个篮球,小朋友可以在桶左边或者右边取出篮球,当桶里只有一个篮球的情况下,只能从桶的左边取出。

例如,老师按顺序放入 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 ”;

输入描述:

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

输出描述:

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

特别注意事项:
1、1<=篮球的编号,篮球个数<=200;
2、篮球上的数字不重复;
3、输出的结果中 LR 的必须为大写;

示例1:

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


输出
RLRRRLL
说明:篮球的取出顺序依次为 “右,左,右,右,右,左,左”

示例2:

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


输出:
NO
说明:无法取出对应序列的篮球

示例3:

输入
1,2,3,4
1,2,3,5


输出
NO
说明:不存在编号为 5 的篮球,所以无法取出对应的编号数据

C++源码:

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

using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    queue<int> ball, get;
    deque<int> list;
    string input;
    getline(cin, input);  // 获取第一行数据,篮球的放入顺序
    stringstream ss(input);
    string temp;

    while (getline(ss, temp, ',')) {
        ball.push(stoi(temp));
    }

    getline(cin, input); // 获取第二行数据,篮球的取出顺序
    ss.clear();
    ss.str(input);
    while (getline(ss, temp, ',')) {
        get.push(stoi(temp));
    }

    int ballNum = 0;  // 统计输入的字符串中篮球编号的个数
    for (int i = 0; i < input.size(); i++)
    {
        if (input[i] != ',') {
            ballNum++;
        }
    }

    string direction;  // 对篮球的取出顺序进行记录
    while (!get.empty()) {
        if (list.empty() && !ball.empty()) {
            list.push_back(ball.front());
            ball.pop();
        }
        if (list.empty()) {
            break;
        }
        int tempL = list.front(), tempR = list.back();
        int temp = get.front();
        if (temp == tempL) {
            get.pop();
            list.pop_front();
            direction = direction + 'L';
        }
        else if (temp == tempR) {
            get.pop();
            list.pop_back();
            direction = direction + 'R';
        }
        else {
            if (ball.empty()) {
                break;
            }
            list.push_back(ball.front());
            ball.pop();
        }
    }

    // 输出取出顺序
    if (ballNum == direction.size()) {
        cout << direction << endl;
    }
    else {
        cout << "NO" << endl;
    }

    system("pause");
    return 0;
}

### 华为OD机考数大雁真题及答案解析 #### 题目描述 给定一个字符串 `croakOfFrogs`,表示不同时间点听到的大雁叫声。每只大雁发出的声音序列严格遵循 "quack" 的顺序。返回能够产生所给字符串的最少大雁数量。如果该字符串不是有效的组合,则返回 `-1`。 条件如下: - 输入字符串长度范围:\( 1 \leq croakOfFrogs.length \leq 10^5 \) - 字符串中的字符仅限于 'q', 'u', 'a', 'c' 或者 'k' #### 解决方案 为了计算最小的大雁数量,可以维护五个计数器来跟踪当前正在发声的不同阶段的大雁数目。每当遇到一个新的起始字母(即 'q'),增加相应计数器;当完成一次完整的 “quack” 声音循环时减少这些计数器。还需要确保任何时候后面的字母不会超过前面的字母的数量,否则就不是一个合法的输入[^1]。 下面是具体的实现方法: ```cpp class Solution { public: int minNumberOfGeese(string croakOfGeese) { unordered_map<char, int> count{{'q', 0}, {'u', 0}, {'a', 0}, {'c', 0}, {'k', 0}}; int max_geese = 0; for (char ch : croakOfGeese) { ++count[ch]; // Check the order of characters to ensure validity. if (!(count['q'] >= count['u'] && count['u'] >= count['a'] && count['a'] >= count['c'] && count['c'] >= count['k'])) { return -1; } // Update maximum number of geese at any point in time. max_geese = std::max(max_geese, *std::max_element(count.begin(), count.end(), [](const auto& p1, const auto& p2) { return p1.second < p2.second; })); // When a full sequence is completed ('quack'), decrement all counters by one. if (ch == 'k') { for (auto& pair : count) { --pair.second; } } } // Ensure no incomplete sequences are left over. for (int val : count.values()) { if (val != 0) return -1; } return max_geese; } }; ``` 此代码通过遍历整个字符串并保持对每个声音部分的追踪来解决问题。它还验证了每次读取新字符后的合法性,并在检测到完整的一轮发音后重置计数器。最后检查是否有未完成的序列存在,如果有则返回错误码 `-1`,否则返回最大并发大雁数量作为结果[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值