算法题--报数游戏

有 n (1<n<10000)个小朋友站成一个圆圈。
选定一个小朋友为1号,从他(她)开始顺时针编号:1,2,3,4,…

游戏开始! 从1号小朋友起,顺时针报数,从1报起。
即:1号小朋友报1,2号小朋友报2,3号小朋友报3, ….

游戏规定,报到数字 m(1<m<100) 的小朋友立即退出报数圈。
在他(她)的顺时针方向的下一个小朋友(如果有的话)开始重新从1报数…
游戏这样一直进行下去,直到圈中只剩下一个小朋友。

求最后剩下的小朋友的编号。

输入:两个整数,n 和 m, 用空格分开。含义如上。

输出:一个整数,表示最后剩下的小朋友的编号。

比如:
输入:
15 3
程序应该输出:
5

再比如:
输入:
7 4
程序应该输出:
2

资源约定:
峯值内存消耗(含虚拟机) < 256M
CPU消耗  < 1000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。

解题思路:从题目明显可以得出这是一个典型的约瑟夫环问题,常规做法就是使用链表来解决此类问题。

代码示例

import java.util.LinkedList;
import java.util.ListIterator;
import java.util.Scanner;

public class Main {

	public static void main(String[] args) {

		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		int m = in.nextInt();

		System.out.println(yuesefu(n, m));

	}

	private static Integer yuesefu(int n, int m) {

		//构建双向链表
		LinkedList<Integer> list = new LinkedList<Integer>();
		//初始化数据
		for (int i = 1; i <= n; i++) {
			list.add(i);
		}
		int start = 1;
		while (list.size() > 1) {
			//构建链表迭代器
			ListIterator<Integer> iterator = list.listIterator();
			while (iterator.hasNext()) {
				iterator.next();
				if (start == m) {
					iterator.remove();
					start = 1;
				} else {
					start++;
				}
			}
		}

		return list.get(0);
	}

}

 

点赞