约瑟环问题:
17世纪的法国数学家加斯帕在《数目的游戏问题》中讲的一个故事,15个教徒和15个非教徒在深海上遇险,必须将一半的人投入海中,其余的人才能幸免于难,于是想了一个办法,30个人围成一个圆圈,从第一个人开始依次报数,每数到第九个人,就将他扔入大海,如此循环进行,直到仅剩余15个人为止。问怎样排法,才能使每次投入大海的都是非教徒
解析:
投海条件: 第九个人, 已投海不计入计算
结束条件: 15人
人的状态:已投海和未投海
看到两种状态就应该想到可以使用一个boolean数组记录状态, 默认都是未投海
遍历该数组,如果当前位置已经为true(已投海),则继续下一位,如果为false则判断是否是第九个人是的话将其投海, 死亡人数+1总人数-1, 不是第九个将其作为计算因子继续向下
以下为Java核心代码:
/**
* @author: Ares
* @description:
* @date: 2020/5/21 17:39
* @param: [personNum, deathNum, surviveNum]
* 总人数, 需要死去的那个人, 存活人数
* @return: void 响应参数
*/
public void deal(int personNum, int deathNum, int surviveNum)
{
boolean[] flags = new boolean[personNum];
// 有效坐标, true是已经死亡的人不会被计算
int vaildPos = 0;
int pos = 0;
int alreadyDeath = 0;
while(alreadyDeath < personNum - surviveNum)
{
int index = pos % personNum;
if (!flags[index])
{
if (vaildPos % deathNum == 8)
{
flags[index] = true;
alreadyDeath++;
System.out.println("我是第" + (index + 1) + "个人, 我没了");
}
vaildPos++;
}
pos++;
}
}
就酱