问题描述
有n个小朋友围成一圈玩游戏,小朋友从1至n编号,2号小朋友坐在1号小朋友的顺时针方向,3号小朋友坐在2号小朋友的顺时针方向,……,1号小朋友坐在n号小朋友的顺时针方向。
游戏开始,从1号小朋友开始顺时针报数,接下来每个小朋友的报数是上一个小朋友报的数加1。若一个小朋友报的数为k的倍数或其末位数(即数的个位)为k,则该小朋友被淘汰出局,不再参加以后的报数。当游戏中只剩下一个小朋友时,该小朋友获胜。
例如,当n=5, k=2时:
1号小朋友报数1;
2号小朋友报数2淘汰;
3号小朋友报数3;
4号小朋友报数4淘汰;
5号小朋友报数5;
1号小朋友报数6淘汰;
3号小朋友报数7;
5号小朋友报数8淘汰;
3号小朋友获胜。
给定n和k,请问最后获胜的小朋友编号为多少?
输入格式
输入一行,包括两个整数n和k,意义如题目所述。
输出格式
输出一行,包含一个整数,表示获胜的小朋友编号。
样例输入
5 2
样例输出
3
样例输入
7 3
样例输出
4
数据规模和约定
对于所有评测用例,1 ≤ n ≤ 1000,1 ≤ k ≤ 9。
这个算法是自己写的,希望各路大佬能指出不足的地方。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner read = new Scanner(System.in);
int n = read.nextInt();
int k = read.nextInt();
node[] Array = new node[n];
for(int i=0;i<n;i++) {
Array[i] = new node(i+1,1); //从1到n给玩家赋值,让其初始值大于0,便于运算判断。
}
int c = 0; //记录淘汰人的个数
int sign = 1; //标记报数的值
int j = 0; // 表示数组的下标
while(c<n-1) { //当淘汰人数达到 n-1时,剩下的最后一个人即为胜利
if(Array[j].count>0) {
Array[j].count = sign;
if(Array[j].count%k==0) { //如果报数到k的倍数
Array[j].count = -1; //标记count为-1,即为淘汰
c++;
}else { //如果报数到的数不是k的倍数,判断数的个位数是否等于k
int d = Array[j].count % 10;
if(d == k) {
Array[j].count = -1; //标记count为-1,即为淘汰
c++;
}
}
}
j++;
if(j==n) //当扫描到最后一个人是,第一个又接上 循环链表
j=0;
while(Array[j].count<0) { //当遍历到的人的count值为-1,视为已淘汰,则不再让其进行报数。
j++;
if(j==n) //当扫描到最后一个人是,第一个又接上 循环链表
j=0;
}
sign++; //报数的数字
}
for(int i=0;i<n;i++) { //当游戏结束后,有且仅有一人的count值大于零,输出其编号即可
if(Array[i].count>0) {
System.out.println(Array[i].number);
}
}
}
}
class node{
public int number; //玩家编号
public int count; //游戏报的数字
public node(int number,int count) {
this.number = number;
this.count = count;
}
}