/**
*使用JAVA解决依次出局问题 --作者:郴州拓职任文敏
*------------------------------------------------------------------------------
*问题描述
* 设有N个人围坐,编号为1..N,
* 从1开始报数,报到M时,该人出局;剩下者再从1开始报数,报到M的人就出局
* 以此循环类推,求:
* 最后出局的人的编号
* 依次显示每个出局者编号
*解题思路
* 制定一个算法,该算法在一个数组中,每次从N1开始往后推算,找到一个不为0的,
* 则认为报了一个数,报了M个则认为找到了出局者,则
* 将数组该位置数字存到另一数组中,随后将其设为0以表示出局
* 该算法不断自我调用,直到找到最后一个出局者
*/
class Test {
int[] nums;
int[] numsbak;
int n1; //每次查找的起始位置的前一个
int n2; //出局者编号在numsbak数组中的存放位置
int ok; //找到的出局者数量
int incre; //出局条件(点到几个谁就出局)
final int inicnt = 15; //数组大小,改变它即可改变人数
//初始化数据
public Test(){
nums = new int[inicnt];
numsbak = new int[inicnt]; //numsbak数组将依次存放每个出局者号码
//nums数组,存放每个人号码,这里号码从1开始,到inicnt
for(int i=1;i<=inicnt;i++) {
nums[i-1] = i;
}
n1 = -1; //第一次将从0开始找,所以将n1设为-1,以便下次其递增1个即可为0
n2 = 0; //第一次找到的出局者编号将存放到numsbak的首位置,所以将n2设置为0
ok = 0; //目前还没有1个出局者,所以ok设置为0
incre = 4; //每点到4,该人就出局
}
public void findnext(){
int cnt = 0;
while(true){
n1++;
if(n1==inicnt) //找到最后一个之后的一个,其应为0(回头找)
n1 = 0;
if(nums[n1]!=0){ //=0的就已经出局了,所以找!=0的
cnt++; //找到一个!=0的就点下数
/**
* 已经找到incre个,则该人就该出局了,则
* 将该人号码存放到numsbak[n2]处,随后
* 使n2加1,以便下次存放出局者号码,随后
* 将nums[n1]设置为0,表明该人已经出局,随后
* ok加1,说明又找到1个出局者了
*/
if(cnt==incre){
numsbak[n2] = nums[n1];
n2++;
nums[n1] = 0;
ok++;
break;
}
}
}
if(ok<inicnt) //还没有找到所有的出局者,则反复调用自身查找下一个出局者
findnext();
else{
System.out.println("最后出局者:"+numsbak[inicnt-1]);
System.out.println("----------------------------------------");
System.out.println("依次出局者为:");
//下面是依次显示出局人员号码
for(int i=0;i<inicnt;i++){
System.out.println(numsbak[i]);
}
}
}
public static void main(String[] args) {
Test test = new Test();
test.findnext();
}
}