比如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]);
}
}