问题描述
学校给高一(三)班分配了一个名额,去参加奥运会的开幕式。每个人都争着要去,可是名额只有一个,怎么办?班长想出了一个办法,让班上的所有同学(共有n个同学)围成一圈,按照顺时针方向进行编号。然后随便选定一个数m,并且从1号同学开始按照顺时针方向依次报数,1, 2, …, m,凡报到m的同学,都要主动退出圈子。然后不停地按顺时针方向逐一让报出m者出圈,最后剩下的那个人就是去参加开幕式的人。
要求
用环形链表的方法来求解。所谓环形链表,即对于链表尾结点,其next指针又指向了链表的首结点。基本思路是先创建一个环形链表,模拟众同学围成一圈的情形。然后进入循环淘汰环节,模拟从1到m报数,每次让一位同学(结点)退出圈子。
输入格式
输入只有一行,包括两个整数n和m,其中n和 m的含义如上所述。
输出格式
输出只有一个整数,即参加开幕式的那个人的编号。
输入输出样例
样例输入
8 3
样例输出
7
解答
emm之前做没看具体要求,使用了数组内取余循环做法,解题如下:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int m = scanner.nextInt();
int[] nums = new int[n];
for (int i = 0; i < nums.length; i++) {
nums[i] = i+1;
}
// 辅助
int index = 0;
// 淘汰人数
int out = 0;
while (out < n-1) {
int temp = 0;
while (temp < m) {
if (nums[index] != 0) temp++;
index = (++index)%n;
}
if (index != 0)
nums[index-1] = 0;
else nums[n-1] = 0;
out++;
}
for (int i = 0; i < nums.length; i++) {
if (nums[i] != 0) {
System.out.print(nums[i]);
break;
}
}
}
}
再写一个单向环形链表做法,做法如下:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// 读入数据
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int m = scanner.nextInt();
scanner.close();
// 初始化
CircleLink circleLink = new CircleLink(1);
for (int i = 2; i <= n; i++) {
circleLink.addNode(i);
}
// 开始循环去除
Node temp = circleLink.getFirst();
while (circleLink.getSize() > 1) {
for (int i = 1; i < m; i++) {
temp = temp.getNext();
}
circleLink.deleteNode(temp);
temp = temp.getNext();
}
// 输出参加者
System.out.println(circleLink.getFirst().getValue());
}
}
/**
* 单向环形链表节点
*/
class Node {
private int value = 0;
private Node next = null;
public Node() {
}
public Node(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
/**
* 单向环形链表
*/
class CircleLink {
private Node first = null;
private int size = 0;
public CircleLink(int value) {
first = new Node(value);
first.setNext(first);
size = 1;
}
/**
* 添加
* @param value
*/
public void addNode(int value) {
Node temp = first;
// 走到链尾
while (temp.getNext() != first) temp = temp.getNext();
Node node = new Node(value);
temp.setNext(node);
node.setNext(first);
size++;
}
/**
* 删除
* @param node
*/
public void deleteNode(Node node) {
Node temp = first;
while (temp.getNext() != node) temp = temp.getNext();
if (node == first) {
first = node.getNext();
}
temp.setNext(node.getNext());
size--;
}
public Node getFirst() {
return first;
}
public int getSize() {
return size;
}
}