设有N个人围坐一圈并按顺时针方向从1到N编号,从第S个人开始进行1-M报数,报数到第M的人,此人出圈,在从他的下一个人重新开始从1-M报数,如此进行下去,每次报数到M的人就出圈,直到所有人都出圈为止。给出这N个人的出去按顺序。
package exercise; // 约瑟夫环问题 public class Joseph_le { public static void main(String[] args) { // TODO 自动生成的方法存根 final int N = 13,S = 3,M = 5;//N为总人数,从第S个人开始报数,报数到M的出圈 int[] p = new int[N];//数组p用于标识已出圈的人 int[] q = new int[N];//数组q存放出对顺序 int k = 0; int n = 0; k = S - 2;//k从1开始数出圈人的下标 for(int i = 1;i <= N;i++) { for(int j = 1;j <= N;j++)//从1到M报数,计算出圈人的下标k { if(k == N-1) //当出圈人的下标达到末尾时 k = 0; //出圈人的下标从0开始 else k++;//否则下标加1 if(p[k] == 1)//若P{k}=1‘说明下标为k的人已出圈 j--;//由于让过已出圈的人,所以J需要-1,以保证每次数过M个人 } p[k] = 1;//将下标为K的数组元素置1,表示其出圈 q[n++] = k + 1;//将下标为K的人的编号k+1存在数组元素q[n]中 } System.out.println("出队顺序为:"); for(int i = 0;i < N;i++) System.out.print(q[i] + " "); } }
该程序运行结果如下:
出队顺序为:
2 3 5 8 12 7 4 6 11 13 1 9 10