约瑟夫环问题
问题:有N个人围成一圈,顺序排号。从第一个人开始报数(从1~~3报数),凡报到3的退出圈子,问最后留下的人原来是排在第几号?
请编程实现之。
思路:
(1)用一个循环队列array(用数组或者链表模拟循环队列都可)去存放这个n个人组成的圈子.
(2)然后依次开始报数,用变量currentCallNum表示当前报数(根据题意,从1开始),用index表示数组里面每个元素的下标(下标从0开始)
(3)当有人需要出圈的时候,就把array[index%n]置为-1,然后整个队列的长度len减1
(4)最后当队列长度为1时,遍历这个队列,返回值不为1的位置即可.
代码(Java)实现如下:
public class Joseph1 { public static void main(String[] args) { System.out.println("最后留下的人原来排在:" + pickup(11, 3) + "号!"); } public static int pickup(int n, int m) { // 用数组去模拟这个循环队列 int[] array = new int[n]; for (int i = 0; i < n; i++) { array[i] = i + 1; } int len = n; // currentCallNum表示当前报数(根据题意,从1开始) int currentCallNum = 1; // 用index表示数组里面每个元素的下标(下标从0开始) int index = 0; while (len != 1) { // 判断该位置是否有人 if (array[index % n] != -1) { // 判断该位置上的人是否应该出圈 if (currentCallNum % m == 0) { // 把array[index%n]置为-1,然后整个队列的长度len减1 array[index % n] = -1; len--; } // 位置上有人,才报数,没有人则不需要报 currentCallNum++; } index++; } int lastPersonPos = 0; // 最后当队列长度为1时,遍历这个队列,返回值不为1的位置即可. for (int i = 0; i < array.length; i++) { if (array[i] != -1) { lastPersonPos = array[i]; } } return lastPersonPos; } }
作者:
Chris Wang
出处:
http://chriswang.cnblogs.com/
文章版权归本人所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。