网站首页 > 技术文章 正文
一、题目描述
每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友。其中有个游戏规则如下:
- 让小朋友们围成一个大圈,小朋友编号从0到n-1;
- 随机指定一个数m,从编号为0的小朋友开始报数;
- 每次喊到m-1的小朋友要出列唱首歌,然后不再回到圈中;
- 从出列小朋友的下一个小朋友开始,继续按0...m-1的规则报数;
- 重复上述过程,直到剩下最后一个小朋友,该小朋友可获得“名侦探柯南”典藏版礼品。
要求:求出最终获得礼品的小朋友编号。
二、解题思路
若仅需求最后一个报数胜利者的编号,可通过数学归纳法推导解决方案,具体分析如下:
1. 问题转换
将原问题抽象为数学模型:n个人(编号0~n-1)围成圈,从0开始报数,报到m-1的人退出,剩余的人继续从0报数,求最终胜利者的编号。
2. 子问题推导
当第一个人(编号为k = m % n - 1)出列后,剩余n-1人组成新的“约瑟夫环”,新环的起始编号为k + 1(即原编号k的下一个人),新环的编号序列为:
k, k+1, k+2, ..., n-2, n-1, 0, 1, 2, ..., k-2
为简化计算,对新环编号做映射转换,将其转化为n-1人游戏的标准模型(从0开始连续编号):
新环原编号 映射后编号 k 0 k+1 1 k+2 2 ... ... k-2 n-2
3. 递推公式推导
设f[i]表示“i个人玩游戏,报m退出”场景下最终胜利者的编号,则:
- 边界条件:当只有1个人时(i=1),胜利者只有自己,即f[1] = 0;
- 递推关系:若已知i-1人游戏的胜利者编号为f[i-1],则i人游戏的胜利者编号可通过映射逆运算得到,公式为:
f[i] = (f[i-1] + m) % i(i>1)
三、C# 代码实现
public class Solution
{
/// <summary>
/// 求解圆圈中最后剩下的数(约瑟夫环问题)
/// </summary>
/// <param name="n">初始人数(编号0~n-1)</param>
/// <param name="m">报数阈值(报到m-1的人出列)</param>
/// <returns>最终胜利者的编号,若输入无效则返回-1</returns>
public int LastRemaining_Solution(int n, int m)
{
// 输入合法性校验:人数n或报数阈值m小于1时,无有效结果
if (n < 1 || m < 1)
{
return -1;
}
// 初始值:1人时胜利者编号为0
int last = 0;
// 从2人开始递推,直到计算出n人时的结果
for (int i = 2; i <= n; i++)
{
last = (last + m) % i;
}
return last;
}
}
代码说明
- 输入校验:首先判断n和m是否为正整数,若存在非正整数则返回-1(无效场景);
- 初始值设定:last初始化为0,对应“1人游戏”的胜利者编号;
- 循环递推:从2人游戏开始,通过公式(last + m) % i逐步计算每增加1人后的胜利者编号,最终得到n人游戏的结果;
- 时间复杂度:O(n),仅需一次循环遍历;
- 空间复杂度:O(1),仅使用常量级额外空间。
猜你喜欢
- 2025-08-31 HashMap详解_hashmap lru
- 2025-08-31 一招教你搞定西门子博图SCL编程语句中FOR循环指令,so easy
- 2025-08-31 JAVA序列化那些事儿_java序列化方式和作用
- 2025-08-31 雨刮器的INT功能你真的会用吗?别再当摆设了,老司机手把手教你
- 2025-08-31 认识变量与常量_变量与常量的定义
- 2025-08-31 PLC数学函数有哪些呢_plc常用的数学计算
- 2025-08-31 python中字典详解及使用_python里字典怎么用
- 2025-08-31 算法“动态规划”最佳实践——背包问题
- 2025-08-31 大语言模型解释Python 命令行参数详解
- 2025-05-27 Python进阶 - day1:深入理解数据结构
- 09-04综艺做成这样都上不了热搜?_综艺节目热播原因
- 09-04webRTC中音频相关的netEQ(二):数据结构
- 09-04每日一词“era”_每日一页歌词
- 09-04css 布局简述_简述css布局技术的特点
- 09-049个专业级别的CSS技巧区分了解和精通的鸿沟
- 09-04BeautifulSoup如何将含有data-tag标签的元素提取出来?
- 09-04CSS 中实现动画效果的方法_css动画制作
- 09-045个CSS新功能,简单好用还超省时间
- 最近发表
- 标签列表
-
- cmd/c (90)
- c++中::是什么意思 (84)
- 标签用于 (71)
- 主键只能有一个吗 (77)
- c#console.writeline不显示 (95)
- pythoncase语句 (88)
- es6includes (74)
- sqlset (76)
- windowsscripthost (69)
- apt-getinstall-y (100)
- node_modules怎么生成 (87)
- chromepost (71)
- flexdirection (73)
- c++int转char (80)
- mysqlany_value (79)
- static函数和普通函数 (84)
- el-date-picker开始日期早于结束日期 (76)
- asynccallback (71)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- java (73)
- js数组插入 (83)
- mac安装java (72)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)