[LeetCode][LCR187]破冰游戏——约瑟夫环

题目

LCR 187. 破冰游戏

社团共有 num 位成员参与破冰游戏,编号为 0 ~ num-1。成员们按照编号顺序围绕圆桌而坐。社长抽取一个数字 target,从 0 号成员起开始计数,排在第 target 位的成员离开圆桌,且成员离开后从下一个成员开始计数。请返回游戏结束时最后一位成员的编号。

  • 示例 1:

输入:num = 7, target = 4

输出:1

  • 示例 2:

输入:num = 12, target = 5

输出:0

  • 提示:
    1 <= num <= 10^5
    1 <= target <= 10^6

思考

  1. 就本题这个数量级,直接模拟肯定会超时,必有某种数学方式进行求解
  2. 其实本题是著名的 "约瑟夫环" 问题,描述如下:
  • 约瑟夫环(Josephus problem)最初的版本可以追溯到古代历史。这个问题据说最早出现在犹太历史学家弗拉维约斯·约瑟夫斯(Flavius Josephus)的著作《犹太古史》中。在这个传奇式的故事中,约瑟夫斯和他的40个士兵被罗马军队包围。他们决定宁可自杀也不被俘虏,于是他们决定围成一个圈,按照一定的规则自杀,以避免被捕。

  • 问题的描述是:约瑟夫斯和他的士兵为了避免被俘,决定站在一个圆圈内,并且每次从一个人开始,依次数到第k个人,然后将被淘汰的人移出圆圈。那么最终存活下来的人是哪一个呢?

  • 这个问题在数学和计算机科学领域中有很多变种和应用。常见的形式包括不同的起始位置和不同的淘汰间隔等。

解法

  1. 首先设一共有 num 个人,每轮去掉一个人,最终剩下一个人,也就是进行了 num-1 轮

  2. 游戏的关键不是每个人的编号,而是最终留下来的那个人在环中的位置

  3. 可以一次次进行游戏去掉一个个人,如果反过来,也可以恢复去掉的人,从一个人恢复到 num 个人

  4. 在只有一个人的情况下,解就是 0 号位置,也就是如果要把剩下的一个人也去掉,必然是去掉 0 号位置的人

  5. 那么怎么从一个人恢复到 num 个人呢?我们需要得到每次被去掉的数的位置:

    1人->2人
    num-1 轮去掉的数的位置 =(0号位置 + 每次跳跃数 target)% 加入新的数后本轮剩下的人数
    num-1 轮去掉的数的位置=(0+target)%2

    2人->3人
    num-2 轮去掉的数的位置 =(num-1 轮去掉的数的位置 + 每次跳跃数 target)% 加入新的数后本轮剩下的人数
    num-2 轮去掉的数的位置=(num-1 轮去掉的数的位置+target)%3


cpp 复制代码
class Solution {
public:
    int iceBreakingGame(int num, int target) {
        // 每一次去除的人的位置 x
        // 在剩下一个人的情况下,
        // 这个位置是幸存者,
        // 也是下一轮剩0人的时候要去除的位置
        int x=0;
        for(int i=2; i<=num; ++i){
            x = (x+target)%i;
        }
        return x;
    }
};
相关推荐
CM莫问2 小时前
<论文>(微软)WINA:用于加速大语言模型推理的权重感知神经元激活
人工智能·算法·语言模型·自然语言处理·大模型·推理加速
计信金边罗4 小时前
是否存在路径(FIFOBB算法)
算法·蓝桥杯·图论
MZWeiei4 小时前
KMP 算法中 next 数组的构建函数 get_next
算法·kmp
Fanxt_Ja5 小时前
【JVM】三色标记法原理
java·开发语言·jvm·算法
luofeiju5 小时前
行列式的性质
线性代数·算法·矩阵
緈福的街口6 小时前
【leetcode】347. 前k个高频元素
算法·leetcode·职场和发展
pen-ai6 小时前
【统计方法】基础分类器: logistic, knn, svm, lda
算法·机器学习·支持向量机
鑫鑫向栄6 小时前
[蓝桥杯]春晚魔术【算法赛】
算法·职场和发展·蓝桥杯
roman_日积跬步-终至千里6 小时前
【Go语言基础【3】】变量、常量、值类型与引用类型
开发语言·算法·golang
FrankHuang8887 小时前
使用高斯朴素贝叶斯算法对鸢尾花数据集进行分类
算法·机器学习·ai·分类