比如n=3,m=4
有3个人,从1报到4
第一次出队:1号
第二次出队:3号
最后留下:2号
使用链表来做最方便。
import java.util.Scanner; public class LastOneStanding { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.print("请输入人数n和报数范围m:"); int n = sc.nextInt(); int m = sc.nextInt(); int[] nums = new int[n]; // 存储每个人的编号 for (int i = 0; i < n; i++) { nums[i] = i + 1; } int lastIdx = 0; // 最后一个留下的人的编号初始化为0 while (nums.length > 1) { // 当链表长度大于1时,继续循环 int startIdx = 0; // 从哪个位置开始报数 if (lastIdx == nums.length - 1) { // 如果上一个人是最后一个离开的人,从头开始报数 startIdx = 0; } else { // 否则从上一个人的下一个位置开始报数 startIdx = lastIdx + 1; } for (int i = startIdx; i < nums.length; i++) { // 从指定位置开始报数 if (i == m) { // 如果报到m的人出去了,更新链表头指针和剩余人数 int nextIdx = nums[i % nums.length]; nums[0] = nextIdx; lastIdx = 0; if (nums.length == 1) { // 如果链表长度为1,说明只剩下一个人了,输出他的编号 System.out.println(nums[0]); break; } nums[1] = nums[nums.length - 1]; // 将尾节点接在头节点后面,形成一个单节点的循环链表 nums[nums.length - 1] = 0; // 将尾节点置为0,表示已经删除掉该节点 nums[0] = i + 1; // 将新节点的编号设为i+1,表示该节点是新的头节点 } else { // 如果没有报到m的人,将当前节点的编号加入到剩余人数中,并更新链表头指针和剩余人数 lastIdx++; } } } System.out.println("最后留下的人的编号为:" + nums[0]); } }