据说著名犹太历史学家 Josephus 有过以下故事:在罗马人占领乔塔帕特后,39 个犹太人与 Josephus 及他的朋友躲到一个洞中,39 个犹太人决定宁愿死也不要被敌人抓到,于是决定了一种自杀方式,41 个人排成一个圆圈,由第 1 个人开始报数,报数到 3 的人就自杀,然后再由下一个人重新报 1,报数到 3 的人再自杀,这样依次下去,直到剩下最后一个人时,那个人可以自由选择自己的命运。这就是著名的约瑟夫问题。

假设n表示人数,m表示报到m的人自杀,求最终存活的人。

一、编号与报数的关系

原型

约瑟夫环_数学

编号与报数的关系如下,i为当前节点数。

约瑟夫环_递推_02

二、新编号与老编号的关系

如编号3被删除,

旧编号:1 2 3 4 5 6 7

新编号:5 6 x 1 2 3 4

假设被删除的节点的编号为s,i为旧节点个数,则

约瑟夫环_递推_03

约瑟夫环_数学_04

约瑟夫环_java_05

约瑟夫环_java_06

那么,最终剩余的一个节点编号为1,根据递推,可获得该节点最初的编号。

import java.util.Scanner;

public class Main {

public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
int n = in.nextInt();
int m = in.nextInt();
int ans = 1;
for (int i = 2; i <= n; ++i) {
ans = (ans + m - 1) % i + 1;
}
System.out.println(ans);
}
}
}


心之所向,素履以往 生如逆旅,一苇以航