小白也能看懂的约瑟夫环问题
首先,我先澄清一下标题,我是小白,我看懂了(●ˇ∀ˇ●)
约瑟夫环是一个数学的应用问题:已知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(如果超出了当前人数,就%当前人数,也就是从头继续数)