记得做个一个类似的问题,就是大家围城一个圈,然后依次数数,数到特定数的退出,问最后留下谁。今天发现这原来是个很经典的问题:约瑟夫 环
约瑟夫环问题描述如下:
历史学家约瑟夫和友人以及其他39人多在山洞中躲避战乱,除约瑟夫和友人外其他人表示要集体自杀来表明自己绝不投降的志气。做法是41个人围城一个圈,然后顺时针报数,1,2,3.报数为3的人立刻自然,然后下一个人从1重新开始报数。约瑟夫和友人不想自杀,那么他们需要站在为几号的位置?
扩展:我们不妨输入任意一个数n>=3,问按照上面的自杀规则,留下的是几号?
java程序实现如下:
package huawei;
import java.util.Scanner;//用于获得输入
public class Josephus
{
/**
*约瑟夫问题
*/
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
System.out.print("Please input the number of the people:");//提示用户输入游戏人数
int number = in.nextInt();
int[] out = Jose(number);//调用函数获得游戏结束时的数组(状态)
System.out.println("The number of the survive peoples are:");
for(int i = 0; i < number; i++)
{
if (out[i] == 1)
System.out.print(i + 1 + "\t");//得到游戏结束剩下人的编号
}
}
static int[] Jose(int n)
{
int[] num = new int[n];
for (int i = 0; i < n; i++)
{
num[i] = 1;//初始化一个整数数组,为1表示或者为0表示已经自杀。
}
int count = 0, indix = 0, remain = n;//n用于记录剩余人数,indix用于记录游戏者的编号
while(true)
{
if (num[indix] == 1)
{
count++;
if (count % 3 == 0)//数到3的自杀
{
num[indix] = 0;
remain--;
}
}
indix++;
if (indix == 41)
{
indix = 0;
}
if (remain <= 2)
{
return num;
}
}
}
}
输入/输出格式如下:
Please input the number of the people:
41
The number of the survive peoples are:
16 31