题目描述
有 N 个人绕成圆圈,按照顺序排号 (1
-N) ,第一个人从 1
开始依次报数,报到 3
的人淘汰,接下来的人又从 1
开始依次报数,报到 3
的人淘汰;再报数,直到只剩下一个人,问最后留下的是原来第几号的那个人。
输入格式
一个 ≥1
的整数,代表总共有多少人。
输出格式
一个整数,代表最后剩下的人是几号。
输入输出样例
输入格式
10
输出格式
4
说明/提示
排号从 1
开始。
【Java代码及解题思路】
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
// 创建二维数组模拟循环链表,a[i][0]表示第i个人最初的序号,a[i][1]表示第i个人的下一个人序号(下标)
int[][] a = new int[n][2];
// 例如三个人:
// 0 1
// 1 2
// 2 0
for(int i=0;i<n;i++){
if(i==n-1){
a[i][0] = i;
a[i][1] = 0;
}else {
a[i][0] = i;
a[i][1] = i+1;
}
}
// 定义前一个人的下标,淘汰时使用,将此人的next下标给前一个人,相当于将此节点从链表中删除
int preNode = 0;
// 目前喊到几了
int number = 0;
// a数组的索引
int index = 0;
// 淘汰的人数,当淘汰了n-1人时,结束循环
int obsolete = 0;
//循环
while (true){
// 结束循环,并输出最后一人最初的序号
if(obsolete==n-1){
System.out.println(a[index][0]+1);
break;
}
// 如果当前没有喊到3,则继续下一个人
if(number!=2){
// 更新前一个人
preNode = index;
// 更新当前的人
index = a[index][1];
// 喊的数+1
number++;
}else { //如果当前这个人喊到3了,则被淘汰
// 把这人的下一个人的索引给之前的人
a[preNode][1] = a[index][1];
// 更新前一个人
preNode = index;
// 更新当前的人
index = a[index][1];
// 更新淘汰人数
obsolete++;
// 喊的数赋零
number=0;
}
}
}
}