约瑟夫环问题有 n 个人编号为1~ n ,排成一个环,从1号人开始从1到 m 报数,报到 m 的人离开该环,从下一个人开始继续从1到 m 报数,报到 m 的人离开该环,这样一直进行下去,直到最终剩余 p 个人。从键盘输入 n 、 m 、 p ,要求 n >=2、 m >=2、 l <= p < n ,输出最终剩余的 p 个初始编号。例如:输入 n 、 m 、 p 依此为,4、3、2,则输出为1和4。
有帮助的 采纳一下
import java.util.Scanner;
public class Josephus {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入人数n:");
int n = sc.nextInt();
System.out.println("请输入报数m:");
int m = sc.nextInt();
System.out.println("请输入最后剩余人数p:");
int p = sc.nextInt();
if (n < 2 || m < 2 || p <= 0 || p > n) {
System.out.println("输入参数错误!");
return;
}
// 存储编号,开始从1到n
int[] nums = new int[n];
for (int i = 0; i < n; i++) {
nums[i] = i + 1;
}
int count = 0; // 报数
int index = 0; // 数组下标
while (n > p) {
// 报数,计数器+1
count++;
// 如果报到m,则从数组中删除该元素,人数-1
if (count == m) {
nums[index] = 0;
n--;
count = 0; // 重新开始报数
continue;
}
// 下标移动到下一个元素
index++;
if (index == n) index = 0; // 如果下标超出范围,则回到0
// 如果下一个元素为0,则继续移动,知道找到非0元素
while (nums[index] == 0) {
index++;
if (index == n) index = 0;
}
}
// 输出最终剩余人的编号
for (int num : nums) {
if (num != 0) System.out.print(num + " ");
}
}
}
可参考
public class Person {
private int number;
public Person(int number) {
this.number = number;
}
public int getNumber() {
return number;
}
}
public class CircularLinkedList {
private Node head;
private int size;
public void addPerson(int number) {
Person person = new Person(number);
Node newNode = new Node(person);
if (head == null) {
head = newNode;
head.setNext(head);
} else {
Node current = head;
while (current.getNext() != head) {
current = current.getNext();
}
current.setNext(newNode);
newNode.setNext(head);
}
size++;
}
public void removePerson(int m) {
Node current = head;
Node previous = null;
while (size > 1) {
for (int i = 1; i < m; i++) {
previous = current;
current = current.getNext();
}
previous.setNext(current.getNext());
current = current.getNext();
size--;
}
}
public List<Integer> getRemainingPeople(int p) {
List<Integer> remaining = new ArrayList<>(p);
Node current = head;
for (int i = 0; i < p; i++) {
remaining.add(current.getPerson().getNumber());
current = current.getNext();
}
return remaining;
}
private static class Node {
private Person person;
private Node next;
public Node(Person person) {
this.person = person;
}
public Person getPerson() {
return person;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
}
public class JosephusProblem {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("输入人数 (n): ");
int n = scanner.nextInt();
System.out.print("输入计数值 (m): ");
int m = scanner.nextInt();
System.out.print("输入剩余人数(p): ");
int p = scanner.nextInt();
scanner.close();
if (n < 2 || m < 2 || p < 1 || p >= n) {
System.out.println("输入无效");
return;
}
CircularLinkedList circularLinkedList = new CircularLinkedList();
for (int i = 1; i <= n; i++) {
circularLinkedList.addPerson(i);
}
circularLinkedList.removePerson(m);
List<Integer> remainingPeople = circularLinkedList.getRemainingPeople(p);
System.out.println("剩余人员: " + remainingPeople);
}
}
思路:
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("请输入 n:");
int n = input.nextInt();
System.out.print("请输入 m:");
int m = input.nextInt();
System.out.print("请输入 p:");
int p = input.nextInt();
input.close();
List<Integer> list = new ArrayList<>();
for (int i = 1; i <= n; i++) {
list.add(i);
}
int count = 0;
int index = 0;
while (list.size() > p) {
int num = list.get(index);
count++;
if (count == m) {
list.remove(index);
count = 0;
index--;
}
index = (index + 1) % list.size();
}
System.out.println(p);
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i) + " ");
}
}
}
看下面代码,这个是Java语言编写的解决约瑟夫环问题的代码,包括思路逻辑结构和物理结构的实现:
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class JosephusProblem {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入总人数 n: ");
int n = scanner.nextInt();
System.out.print("请输入报数上限 m: ");
int m = scanner.nextInt();
System.out.print("请输入最终剩余人数 p: ");
int p = scanner.nextInt();
if (n < 2 || m < 2 || p >= n) {
System.out.println("输入不符合要求!");
return;
}
List<Integer> people = new ArrayList<>();
for (int i = 1; i <= n; i++) {
people.add(i);
}
int currentIndex = 0;
while (people.size() > p) {
currentIndex = (currentIndex + m - 1) % people.size();
people.remove(currentIndex);
}
System.out.println("最终剩余的 " + p + " 个人的初始编号为:");
for (int number : people) {
System.out.print(number + " ");
}
}
}
思路逻辑结构:
物理结构:
在物理结构上,使用了一个ArrayList来表示约瑟夫环中的人。ArrayList是一个可变长度的数组,可以动态添加、删除元素。通过列表中元素的索引,实现了约瑟夫环的逻辑结构。每次删除一个人时,根据索引进行移除操作,模拟人离开约瑟夫环的过程。最后,剩余的人的初始编号通过遍历列表输出。
思路:这一题,就是n个人按顺时针占成一圈.从第一个位置开始数,数到k就将对应的位置上的人踢出局。不断地重复次操作,直到最后剩下最后一个人,然后输出这个人地序号。