报数游戏 - 华为OD统一考试(E卷)

2024华为OD机试(E卷+D卷+C卷)最新题库【超值优惠】Java/Python/C++合集

题目描述

100个人围成一圈,每个人有一个编号,编号从1开始到100。他们从1开始依次报数,报到为M的人自动退出圈圈,然后下一个人接着从1开始报数,直到剩余的人数小于M。请问最后剩余的人在原先的编号为多少?

输入描述

输入一个整数参数M。

输出描述

如果输入参数M小于等于1或者大于等于100,输出"ERROR!";否则按照原先的编号从小到大的顺序,以逗号分割输出编号字符串。

示例1

复制代码
输入:
3

输出:
58,91

说明:
输入M为3,最后剩下两个人

示例2

复制代码
输入:
4

输出:
34,45,97

说明:
输入M为4,最后剩下三个人

题解

该问题属于循环链表问题 ,可以通过约瑟夫环(Josephus Problem)的思路来解决。这类问题的关键在于模拟一个按固定规则报数和删除的过程。通过循环报数,每次删除报到特定数字的人,并在下次从紧邻剩下的人重新开始报数,直到剩下的人数少于M。


解题思路:

  1. 输入校验 :首先检查输入的整数参数 M 是否在有效范围(1 < M < 100)内。如果无效则输出 "ERROR!"
  2. 初始化队列:使用一个列表或者链表来保存1到100的编号。这个队列将模拟人围成一圈的情况。
  3. 循环删除元素 :从编号为1开始报数,每当报到数字 M 时,移除该人(即从队列中删除该元素),并从下一个人重新开始报数。
  4. 处理循环:为了模拟围成一圈的过程,当到达列表末尾时,需要从头继续开始报数。
  5. 输出结果 :当剩下的人数少于 M 时,按照编号升序输出剩下的编号,以逗号分隔。

Java

java 复制代码
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;

/**
 * @author code5bug
 */
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int M = sc.nextInt();
        if (M <= 1 || M >= 100) {
            System.out.println("ERROR!");
            return;
        }

        List<String> nums = new LinkedList<>();
        for (int i = 1; i <= 100; i++) {
            nums.add(String.valueOf(i));
        }

        Iterator<String> it = nums.iterator();
        for (int now = 1; nums.size() >= M; now++) {
            if (!it.hasNext()) it = nums.iterator(); // 回到开头
            it.next(); // 遍历下一个

            if (now == M) {
                // 注意: Iterator 的 remove() 方法只能在调用 next() 之后使用
                it.remove();
                now = 0;
            }
        }

        System.out.println(String.join(",", nums));	// 输出剩余元素
    }
}

Python

python 复制代码
def main():
    M = int(input())
    if M <= 1 or M >= 100:
        print("ERROR!")
        return

    nums = [str(i) for i in range(1, 101)]  # 初始化编号列表

    index = 0
    now = 1
    while len(nums) >= M:
        if now == M:
            nums.pop(index)	# 删除当前编号
            now = 0	# 重置计数
        else:
            # 如果当前位置是最后一个元素,回到第一个位置(循环列表效果)
            index = (index + 1) % len(nums)
        now += 1

    print(",".join(nums))	# 输出剩余编号


if __name__ == "__main__":
    main()

C++

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

int main()
{
    int M;
    cin >> M;
    if (M <= 1 || M >= 100) {
        cout << "ERROR!" << endl;
        return 0;
    }

    list<int> nums;
    for (int i = 1; i <= 100; i++) nums.push_back(i);

    int now = 1;
    for (auto it = nums.begin(); nums.size() >= M; now++) {
        if (it == nums.end()) it = nums.begin();   // 回到链表开头

        if (now == M) {
            // 注意这里 it = 不要漏写
            it  = nums.erase(it);   // 删除当前元素并更新迭代器
            now = 0;                // 重置计数
        } else {
            it++;
        }
    }

    for (auto it = nums.begin(); it != nums.end();) {
        cout << *it;
        if (++it != nums.end()) cout << ",";
    }
    cout << endl;

    return 0;
}

整理题解不易, 如果有帮助到您,请给点个赞 ‍❤️‍ 和收藏 ⭐,让更多的人看到。🙏🙏🙏

相关推荐
pyniu1 天前
Spring Boot租房管理系统
java·spring boot·后端
No0d1es1 天前
2025年12月 GESP CCF编程能力等级认证Python四级真题
开发语言·python·青少年编程·等级考试·gesp·ccf
love530love1 天前
EPGF 新手教程 13在 PyCharm(中文版 GUI)中创建 Hatch 项目环境,并把 Hatch 做成“项目自包含”(工具本地化为必做环节)
开发语言·ide·人工智能·windows·python·pycharm·hatch
Eloudy1 天前
模板函数动态库与头文件设计示例
算法·cuda
野生技术架构师1 天前
TokenRetryHelper 详解与 Spring Boot 迁移方案
java·spring boot·后端
蚰蜒螟1 天前
Redis网络层深度解析:数据如何写回客户端
java·开发语言·bootstrap
星云数灵1 天前
大模型高级工程师考试练习题4
人工智能·算法·机器学习·大模型·大模型考试题库·阿里云aca·阿里云acp大模型考试题库
千金裘换酒1 天前
Leetcode 二叉树中序遍历 前序遍历 后序遍历(递归)
算法·leetcode·职场和发展
廋到被风吹走1 天前
【Java】新特性最佳实践:避坑指南与性能优化
java·性能优化
效率客栈老秦1 天前
Python Trae提示词开发实战(2):2026 最新 10个自动化批处理场景 + 完整代码
人工智能·python·ai·prompt·trae