Java_案例实例2.约瑟夫环问题

约瑟夫环问题描述:
编号为1-N的N个人按顺时针方向围坐成一圈,从第S个人开始报数(从1报起),报数为M的人出圈,再从他的顺时针方向的下一个人重新开始报数,如此下去,直至所有人出圈为止,给出N个人的出去顺序

算法:
1、设置一个boolean数组out,元素out[i]标记编号为i的人是否已经出圈
2、从编号为S 的人开始,若为报数至M,则继续寻找下一出圈标记为false的 人
3、输出报数为M的人的编号,并修改其对应的出圈标记为true
4、若输出人数未达到M,则继续寻找下一出圈标记为false的人并重新报数,否则结束

源代码:

package ch4_2;

public class JosephRing {

	public static void main(String[] args) {
		// 总人数
		final int N = 13;
		// 从第S个人开始报数
		final int S = 3;
		// 报数为M的人出圈
		final int M = 5;
		// 统一下标与人的标号(自然计数)
		boolean[] out = new boolean[N + 1];

		// 初始化数组
		for (int i = 1; i <= N; i++) {
			// 报数前所有人都未出圈
			out[i] = false;
		}

		// 存放下次开始报数的人的编号
		int i = S;
		// 已出圈的人
		int n = 0;
		// 报数为count的人
		int count;
		System.out.println("出圈顺序:");
		// 仍有人在圈内
		while (n < N) {
			// 出圈后重新计数
			count = 0;
			// 未报数至M
			while (count < M) {
				// 报数的人未出圈
				if (out[i] == false) {
					// 报数
					count++;
				}
				// 未报数至M(上面的if语句可能修改了count)
				if (count < M) {
					// 求下一个的编号(到达N+1则回到第1个人)
					i = (i + 1 > N ? 1 : i + 1);
				}

			}
			// 内层while结束,编号为i的人出圈
			System.out.println(i + " ");
			// 标记出圈的人
			out[i] = true;
			// 又有一人出圈
			n++;
		}
	}

}

猜你喜欢

转载自blog.csdn.net/qq_46672746/article/details/107567912