[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;
    }
};
相关推荐
এ᭄画画的北北8 分钟前
力扣-51.N皇后
算法·leetcode
qqxhb10 分钟前
零基础数据结构与算法——第六章:算法设计范式与高级主题-设计技巧(上)
java·数据结构·算法·分解·空间换时间·时空平衡
1白天的黑夜111 分钟前
前缀和-974.和可被k整除的子数组-力扣(LeetCode)
c++·leetcode·前缀和
11 分钟前
LeetCode Hot 100 搜索二维矩阵
算法·leetcode·矩阵
小新学习屋18 分钟前
《剑指offer》-算法篇-位运算
python·算法·leetcode·职场和发展·数据结构与算法
Swiler18 分钟前
数据结构第2问:什么是算法?
数据结构·人工智能·算法
鼠鼠一定要拿到心仪的offer25 分钟前
Day23-二叉树的层序遍历(广度优先搜素)
数据结构·算法·leetcode
春日轻轨@25 分钟前
SPFA检测负权环
数据结构·c++·算法
YuTaoShao33 分钟前
【LeetCode 热题 100】34. 在排序数组中查找元素的第一个和最后一个位置——二分查找
java·数据结构·算法·leetcode
Jenny1 小时前
第八篇:深度学习基础:神经网络与训练过程
算法·面试