约瑟夫的幸存者问题

问题描述:

n个人编号为1~n,围成一个圈,从第一个人开始报数,123123。。。,报到3的人被踢出,如此循环,直到最后剩下一个人,请问这个人的编号是多少??

方法一:数组解法

import java.util.Scanner;

public class Joseph {

	int[] arr;
	Joseph(int e) {
		arr = new int[e];
	}
	public static void main(String[] args) {
		System.out.print("请输入人数: ");
		Scanner sc = new Scanner(System.in);
		int num = sc.nextInt();
		Joseph j = new Joseph(num);
		for(int i=1; i<=num; i++) {
			j.arr[i-1] = i;
		}
		j.cal();

	}

	void cal() {
		int count = 0;
		int i = 0;
		int sum = 0;
		while(count != arr.length - 1) {
			if(arr[i] != 0) {
				sum++;
				if(sum == 3) {
					count ++;
					arr[i] = 0;
					sum = 0;
				}
			}
			if(i == arr.length - 1) {
				i = 0;
			} else {
				i++;
			}
		}

		for(i=0; i<arr.length; i++) {
			if(arr[i] != 0) {
				System.out.println("幸存者是: " + arr[i] + "号");
			}
		}
	}

}

方法二:循环单链表解法

import java.util.Scanner;

public class Joseph {

	Node head;
	Joseph(int e) {
		head = new Node();
		Node p = head;
		for(int i=1; i<=e; i++) {
			Node n = new Node(i);
			p.next = n;
			p = n;
		}
		p.next = head.next;
		head = head.next;
	}

	void display() {
		Node p = head;
		while(p.next != head) {
			System.out.print(p.data + "->");
			p = p.next;
		}
		System.out.println(p.data);
	}
	public static void main(String[] args) {
		System.out.print("请输入人数: ");
		Scanner sc = new Scanner(System.in);
		int num = sc.nextInt();
		Joseph j = new Joseph(num);

		j.display();
		j.cal();

	}

	void cal() {

		Node p = head;
		int sum = 0;
		while(p.next != p) {

			sum++;
			if(sum == 3) {

				Node pre = pre(p);
				System.out.println("删除 " + p.data + "号");
				pre.next = pre.next.next;

				sum = 0;
			}
			p = p.next;

		}

		System.out.println("幸存者是: " + p.data + "号");
	}

	Node pre(Node p) {
		Node pre = p;;
		while(pre.next != p) {
			pre = pre.next;
		}

		return pre;
	}

}

class Node {
	int data;
	Node next;
	Node(){}
	Node(int e) {
		data = e;
	}
}

结果:

请输入人数: 9
1->2->3->4->5->6->7->8->9
删除 3号
删除 6号
删除 9号
删除 4号
删除 8号
删除 5号
删除 2号
删除 7号
幸存者是: 1号
时间: 2024-10-12 20:36:58

约瑟夫的幸存者问题的相关文章

OI养老专题02:约瑟夫问题求幸存者

如题.人数为n(1<=n<=30000),共k(1<=k<=30000)组数据,所报的数m恒为2. 如果你还不知道什么是约瑟夫问题...——https://www.cnblogs.com/akura/p/10758080.html 如果直接暴力枚举,那么时间复杂度就为O(NM)=O(N),所有数据一共O(KNM)=O(KN).遇上这道题就爆掉了. 那么怎么解决这种大数据的题呢?我们先手玩一把n个人的约瑟夫问题.由于每次对于n取模后的值在[0,n-1]之间,所以我们干脆让所有人的编号

解决约瑟夫环问题

1. 问题描述 一个旅行社要冲n个旅客中选出一名旅客,为他提供免费的环球旅行服务.旅行社安排这些旅客围城一个圈,从帽子中取出一张纸条,用上面写的正整数m(m<n)作为报数值.游戏进行时,从第一个人开始按顺时针方向上的下一个人开始重新报数,如此下去,知道圆圈中只剩下一个人,这个最后的幸存者就是游戏的胜利者,将得到免费旅行的奖励. 2. 问题分析 1)标号分析 可以发现,当人数n,报数值m,人数排列的顺序,和第一个人出局后,接下来剩余的人出局的顺序和最后留下来的人确定了,此时编号只是一个名字,没有实

约瑟夫问题(java实现)

方法一.自定义的链表实现 package com.code.yuesefu; public class YueSeFuList { public static void main(String[] args) { int count = 41;//申请一个指定长度的链表 Node n = YueSeFuList.createNodes(count); for(int i=0;i<count;i++){ Node second = n.next;//第2个 n = n.next.next;//第3

约瑟夫问题的解法集锦

约瑟夫问题的N种解法 1 问题的历史以及不同的版本 1.1  约瑟夫环(Josephus)问题是由古罗马的史学家约瑟夫(Josephus)提出的,他参加并记录了公元66-70年犹太人反抗罗马的起义.约瑟夫作为一个将军,设法守住了裘达伯特城达47天之久,在城市沦陷之后,他和40名死硬的将士在附近的一个洞穴中避难.在那里,这些叛乱者表决说"要投降毋宁死".于是,约瑟夫建议每个人轮流杀死他旁边的人,而这个顺序是由抽签决定的.约瑟夫有预谋地抓到了最后一签,并且,作为洞穴中的两个幸存者之一,他说

C++ 新约瑟夫问题

#include<iostream> #include<cmath> using namespace std; int main() { int n,sum=0,j,i,k,lpl,a[100000],b[100000]; cin>>n; a[1]=1,b[1]=1; for(int i=2;i<=n;i++) { a[i]=(a[i-1]+1)%i+1; if(a[i]==i)b[i]=i; else b[i]=b[a[i]]; } cout<<b[

慈善约瑟夫

Description 你一定听说过约瑟夫问题吧?即从n个人中找出惟一的幸存者.现在老约瑟夫将组织一个皆大欢喜的新游戏,假设n个人站成一圈,从第1个人开始交替的去掉游戏者,但只是暂去掉(例如,首先去掉2),直到最后剩下惟一的幸存者为止. 幸存者选出后,所有比幸存者号码高的人每人将得到1TK(一种货币),永久性的离开.其余剩下的人将重复以上的过程,比幸存者号码高的每人将得到1Tk后离开.经过这样的过程后,一旦人数不再减少,则最后剩下的那些人将得到2TK. 请你计算一下老约瑟夫一共要付出多少钱? A

小朋友学数据结构(1):约瑟夫环的链表解法、数组解法和数学公式解法

约瑟夫环的链表解法.数组解法和数学公式解法 约瑟夫环(Josephus)问题是由古罗马的史学家约瑟夫(Josephus)提出的,他参加并记录了公元66-70年犹太人反抗罗马的起义.约瑟夫作为一个将军,设法守住了裘达伯特城达47天之久,在城市沦陷之后,他和40名死硬的将士在附近的一个洞穴中避难.在那里,这些叛乱者表决说"要投降毋宁死".于是,约瑟夫建议每个人轮流杀死他旁边的人,而这个顺序是由抽签决定的.约瑟夫有预谋地抓到了最后一签,并且,作为洞穴中的两个幸存者之一,他说服了他原先的牺牲品

约瑟夫环-公式递推法

约瑟夫问题 约瑟夫问题是个著名的问题:N个人围成一圈,第一个人从1开始报数,报M的将被杀掉,下一个人接着从1开始报.如此反复,最后剩下一个,求最后的胜利者. 例如只有三个人,把他们叫做A.B.C,他们围成一圈,从A开始报数,假设报2的人被杀掉. 首先A开始报数,他报1.侥幸逃过一劫. 然后轮到B报数,他报2.非常惨,他被杀了 C接着从1开始报数 接着轮到A报数,他报2.也被杀死了. 最终胜利者是C 解决方案 普通解法 刚学数据结构的时候,我们可能用链表的方法去模拟这个过程,N个人看作是N个链表节

环形单链表约瑟夫问题

本文参考博客:https://blog.csdn.net/u011500062/article/details/72855826 约瑟夫问题约瑟夫问题是个著名的问题:N个人围成一圈,第一个人从1开始报数,报M的将被杀掉,下一个人接着从1开始报.如此反复,最后剩下一个,求最后的胜利者. 例如只有三个人,把他们叫做A.B.C,他们围成一圈,从A开始报数,假设报2的人被杀掉. 首先A开始报数,他报1.侥幸逃过一劫.然后轮到B报数,他报2.非常惨,他被杀了C接着从1开始报数接着轮到A报数,他报2.也被杀