n个人(编号 1~n)围成一圈从编号为1的开始报数,从1报到m,报到m的人出来,下一个人继续重新从1开始报数,编程求最后一个留下的人的编号
如 n=3, m=4
第一次出队:1
第二次出队:3
最后留下:2
第一种解法:
import java.util.Scanner;
public class Test04_2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 输入人数n和报到的数m
int n = sc.nextInt();
int m = sc.nextInt();
// 将这些人的编号用数组储存起来
int[] num = new int[n + 1];
// 下标从1开始计数,对应人员编号
for (int i = 1; i <= n; i++) {
num[i] = i;
}
// 退圈的人数
int count = 0;
// 人员编号
int i = 0;
// 报出的数字
int temp = 0;
// 如果只剩下一个人没有退圈就结束循环
while (count != n - 1) {
// 如果这个人没有退圈,就继续报数
if (num[++i] != 0) {
temp++;
}
// 如果这个人报数正好是m,则退圈,对应下标的值变为0,重置报数的数字
if (temp == m) {
num[i] = 0;
temp = 0;
count++;
}
// 报过一轮之后,开始下一轮报数
if (i == n) {
i = 0;
}
}
// 找出最后这个人
for (i = 1; i <= n; i++) {
if (num[i] != 0) {
System.out.println(num[i]);
break;
}
}
}
}
第二种解法:
import java.util.LinkedList;
import java.util.Scanner;
public class Test04 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 输入人数n和报到的数m
int n = sc.nextInt();
int m = sc.nextInt();
// 将这些人的编号用动态数组储存起来
LinkedList<Integer> list = new LinkedList<Integer>();
for (int i = 1; i <= n; i++) {
list.add(i);
}
int i = -1;
int temp = 0;
while (list.size() != 1) {
if (++i >= list.size()) {
i = 0;
}
//删除报数是m的那个人
if (++temp == m) {
list.remove(i);
i--;
temp = 0;
}
}
System.out.println(list.get(0));
}
}