代码不是本人自己所写,是在一本书上看到的,经过了一些改正,但是感觉很好,所以想分享一下
问题描述
问题描述:N个人围成一圈,从第M个人开始报数,报到K的人出圈,剩下的人继续从1开始报数,报到K的人出圈;如此往复,直到所有人出圈。(模拟此过程,输出出圈的人的序号)
以图片为例:
5人围圈,报到3则出局。
第一轮报数
所报数字 | 人的编码 |
---|---|
1 | 1 |
2 | 2 |
3 | 3(出局) |
第二轮报数
所报数字 | 人的编码 |
---|---|
1 | 4 |
2 | 5 |
3 | 1(出局) |
部分代码讲解
预先准备
- 定义数组
int[] ia=new int[N];
Arrays.fill(ia, 1); //将数组都=1
定义一个数组,并将数组所有内容=1,在循环时,每当出局一人则将该人的赋值=0,详细原因请见while循环的讲解
- count
int count=0;
记录人数,当所有人全部出局时,结束循环
while循环讲解
while (count<=N) { //见讲解一
int j=0;
while (true) {
j=j+ia[i];
if (j==K) {
ia[i]=0;
if (i==0) {
System.out.print((i+ia.length)+"\t");
}else {
System.out.print(i+"\t");
}
count++;
break;
}
if (i==ia.length-1) {
i=0;
}else {
i++;
}
}
}
- 讲解一:while循环
while (count<=N) {
while (true) {
}
}
外层循环:count纪录出局人数,N是总共的人数,当count>N时结束循环
内层循环:一个无限循环,再循环内设置了一个break来结束循环
- 讲解二:if讲解
if (j==K) {
ia[i]=0;
if (i==0) {
System.out.print((i+ia.length)+"\t");
}else {
System.out.print(i+"\t");
}
count++;
break;
}
外层if:K表示钥匙(每报到3的人出局),当 j 与K相等时进入循环,即有 a[i] 出局
内层if:由于数组下标是从零开始的,所以我们将 i=0 的时候定义成最后一个数 (如图),当是其他数时,直接输出即可。
if (i==ia.length-1) {
i=0;
}else {
i++;
}
由于数组是一个单向的,所以当循环到数组的最后一个数时,需要将其更改到第一个
完整代码
import java.util.Arrays;
import java.util.Scanner;
public class Joseph {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.print("围桌座的人数:");
int N=sc.nextInt(); //人数
System.out.print("从几号开始报数:");
int M=sc.nextInt(); //开始报号的人
System.out.print("钥匙是:");
int K=sc.nextInt(); //钥匙
int[] ia=new int[N];
Arrays.fill(ia, 1); //将数组都=1
int count=0; //记录出局人数
int i=M;
//利用while循环出局,每次while循环一次都会有一个人出局
while (count<=N) {
int j=0;
while (true) {
j=j+ia[i];
if (j==K) {
ia[i]=0;
if (i==0) {
System.out.print((i+ia.length)+"\t");
}else {
System.out.print(i+"\t");
}
count++;
break;
}
if (i==ia.length-1) {
i=0;
}else {
i++;
}
}
}
}
}