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

429 阅读2分钟

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

约瑟夫环是一个数学的应用问题:已知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(如果超出了当前人数,就%当前人数,也就是从头继续数)
在这里插入图片描述

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

\