约瑟夫环基本版(java)
代码不是本人自己所写,是在一本书上看到的,经过了一些改正,但是感觉很好,所以想分享一下问题描述
问题描述: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,在循环时,每当出局一人则将该人的赋值=0,详细原因请见while循环的讲解
int count=0;
记录人数,当所有人全部出局时,结束循环
while循环讲解
while (count<&#61;N) { int j&#61;0; while (true) {j&#61;j&#43;ia[i];if (j&#61;&#61;K) {ia[i]&#61;0;if (i&#61;&#61;0) {System.out.print((i&#43;ia.length)&#43;"\t");}else {System.out.print(i&#43;"\t");}count&#43;&#43;;break;}if (i&#61;&#61;ia.length-1) {i&#61;0;}else {i&#43;&#43;;}} }
while (count<&#61;N) { while (true) {}
}
外层循环&#xff1a;count纪录出局人数&#xff0c;N是总共的人数&#xff0c;当count>N时结束循环
内层循环&#xff1a;一个无限循环&#xff0c;再循环内设置了一个break来结束循环
if (j&#61;&#61;K) {ia[i]&#61;0;if (i&#61;&#61;0) {System.out.print((i&#43;ia.length)&#43;"\t");}else {System.out.print(i&#43;"\t");}count&#43;&#43;;break;}
外层if&#xff1a;K表示钥匙&#xff08;每报到3的人出局&#xff09;&#xff0c;当 j 与K相等时进入循环&#xff0c;即有 a[i] 出局
内层if&#xff1a;由于数组下标是从零开始的&#xff0c;所以我们将 i&#61;0 的时候定义成最后一个数 &#xff08;如图&#xff09;&#xff0c;当是其他数时&#xff0c;直接输出即可。
if (i&#61;&#61;ia.length-1) {i&#61;0;}else {i&#43;&#43;;}
由于数组是一个单向的&#xff0c;所以当循环到数组的最后一个数时&#xff0c;需要将其更改到第一个
完整代码
import java.util.Arrays;
import java.util.Scanner;public class Joseph {public static void main(String[] args) {Scanner sc&#61;new Scanner(System.in);System.out.print("围桌座的人数&#xff1a;");int N&#61;sc.nextInt(); System.out.print("从几号开始报数&#xff1a;");int M&#61;sc.nextInt(); System.out.print("钥匙是&#xff1a;");int K&#61;sc.nextInt(); int[] ia&#61;new int[N]; Arrays.fill(ia, 1); int count&#61;0; int i&#61;M; while (count<&#61;N) {int j&#61;0; while (true) {j&#61;j&#43;ia[i];if (j&#61;&#61;K) {ia[i]&#61;0;if (i&#61;&#61;0) {System.out.print((i&#43;ia.length)&#43;"\t");}else {System.out.print(i&#43;"\t");}count&#43;&#43;;break;}if (i&#61;&#61;ia.length-1) {i&#61;0;}else {i&#43;&#43;;}} }}
}
运行结果