• 小白也能看懂的约瑟夫环问题


    首先,我先澄清一下标题,我是小白,我看懂了(●ˇ∀ˇ●)

    约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。通常解决这类问题时我们把编号从0~n-1,最后 结果+1即为原问题的解。

    如果还看不懂问题,杨帆兄简单易懂的约瑟夫环

    PS:

    首先附上代码
    这个代码是一共n个人,每次淘汰数到k的个人,问最后剩下的是第几个人

    import java.util.Scanner;
    
    public class 约瑟夫环 {
        public static void main(String[] args) {
            Scanner in = new Scanner(System.in);
            int n = in.nextInt(), k = in.nextInt();
            int p = 0;
            for (int i = 2; i <= n; i++) {
                p = (p + k) % i;
            }
            System.out.println(p + 1);
        }
    }
    
    

    原题是问最后剩下的那个人是几号,可以这么想
    按照正常的逻辑是,最后一个淘汰的人是谁,
    既然是这样,我们反过来想,
    我们可以是开局一个人,
    在这里插入图片描述

    打住,我们回归正题

    这个人肯定是被over的,



    所以我们开局两个人,我们不断的向里面加人,

    思路变成了,我们从第二个人开始,就每次往里面数k个人,
    然后每次%i人数(当前是i个人),因为超过了当前的人数就是要从开头开始数
    我们的p保存的是第几个位置,
    然后一直循环,每次都往里面加一个人
    因为我们的p是从0开始的,所以最后的结果是+1操作



    在这个过程中,我们无需担心删除相同的人,
    在这里插入图片描述
    我们正着推一边,
    我们从n个人开始,每次都删除数到k的人,
    在这个过程中,虽然我们可能每次都删掉了同一个位置的人,但是,
    他不可能是同一个人,因为数到了,就会被淘汰,
    再次数到这个位置上,他已经换成了别人

    在这里插入图片描述
    最后我们总结一下:
    正着:每次都是数到k的位置的人退出,人数-1
    反着:每次人数+1;都数到k(如果超出了当前人数,就%当前人数,也就是从头继续数)
    在这里插入图片描述

    开玩笑,哈哈,有不懂的,或者小编描述的有不对的地方,欢迎评论

  • 相关阅读:
    Lua大整数的实现
    std::allocator在stl容器中使用问题
    深度学习框架安装
    Tensorflow安装使用一段时间后,import时出现错误:ImportError: DLL load failed
    论文解读:SIFA
    多位微软MVP推荐,第一本ASP.NET Core 3.1的书来了
    ASP.NET Core 进程内与进程外的性能对比
    基于Netty的程序主动发送消息
    dbroot文件结构解析(一)
    qtree文件结构解析(二)
  • 原文地址:https://www.cnblogs.com/a1439775520/p/12946109.html
Copyright © 2020-2023  润新知