1. 程式人生 > >約瑟夫環問題的兩種解決方式(遞迴求解和陣列模擬求解)

約瑟夫環問題的兩種解決方式(遞迴求解和陣列模擬求解)

約瑟夫環問題各位Acmer肯定都遇到過,就是給你編號為從0~n-1的n個人,從頭開始報數,報到m的人離場,問最後留下的人是幾號。有兩種方法解決這個問題

第一種:陣列模擬

這種方法沒什麼好說的,就是模擬報數和離場的過程,加個訪問陣列標記一下誰離場了就好了

package HomeWork;

public class JosephRing1 {

	public static int josephring(int a[]){

		int vis[] = new int [17];
		int ans = 0;
		int cnt = 0;
		int i = 0;
		while(true){
			if(i == 17){
				i = 0;
			}
			if(vis[i] == 0){	
				cnt++;
				if(cnt % 3 == 0){
					vis[i] = 1;
					ans++;
					System.out.printf("第%d次離開的人是:%d\n",ans,a[i]);
					if(ans == 16)
						break;
				}
			}
			i++;
		}
			for(i=0;i<17;i++){
				if(vis[i] == 0)
					break;
			}
			return a[i];
		}

		public static void main(String [] args){

			int ans = 0;
			int a[] = new int [17];
			for(int i=0;i<17;i++){
				a[i] = ans++;
			}

			System.out.println("最後留下的是:" + josephring(a) + "號");
		}

	}
第二種:遞迴求解

感覺陣列模擬實在low的一批,所以還有一種數學思想的求法;

我們通過寫幾組簡單資料來發現一些規律,比如有6個人,他們編號分別是0,1,2,3,4,5,規定數到3的人離開,那麼首輪離開的是2,5,第二輪離開的是3,也就是說離開人的編號是(m-1)%n,下一輪編號為0的人是(m + 0)%n,下一輪編號為1的人是(m+1)%n,則下一輪編號為i的人是(m+i)%n。我們設函式X(n)表示n個人中離開的人,則根據關係有X(n) = (m+X(n-1))%n,那麼我們就得到了一個遞迴表示式,終止遞迴的條件是x(1),x(1) = (n+m-1)%n。

package HomeWork;

public class JosephRing2 {
	
	public static int josephring2(int n,int m,int i){
		
		if(i == 1){
			return (n + m-1) % n;
		}
		else{
			return (josephring2(n-1,m,i-1) + m) % n;
		}
	}
	
	public static void main(String [] args){
		
		for(int i=1;i<=16;i++){
			System.out.printf("第%d次離開的人是:%d\n",i,josephring2(17,3,i));
		}
		System.out.printf("最後留下的人是:%d\n",josephring2(17,3,17));
	}
}

可以看到結果是一樣的

相關推薦

問題的解決方式求解陣列模擬求解

約瑟夫環問題各位Acmer肯定都遇到過,就是給你編號為從0~n-1的n個人,從頭開始報數,報到m的人離場,問最後留下的人是幾號。有兩種方法解決這個問題 第一種:陣列模擬 這種方法沒什麼好說的,就是模擬報數和離場的過程,加個訪問陣列標記一下誰離場了就好了 package H

JavaScript實現迴圈佇列與問題的解決

function MyCircularQueue(){ var items = []; //向佇列插入元素 this.enQueue = function(value){ return items

經典例題|多方法解決

本文章將用迴圈連結串列、陣列、遞迴以及迴圈方法對約瑟夫環問題進行講解。其中連結串列法和陣列法會對過程進行模擬,遞迴和迴圈將對約瑟夫環問題進行數學剖析。 問題描述 n個人圍成圈,依次編號為1、2、3、...、n,從1號開始依次報數,當報到m時,報m的人退出,下一個人重新從1報起,當報到m時,報m的人退出,如

的c語言實現代碼已實現

def 數字 com max std urn img pri c語言實現 # include <stdio.h> #define MAXLEN 20 int front=MAXLEN-1;//隊列初始化 int rear=MAXLEN-1; enqu

的c語言實現程式碼已實現

# include <stdio.h>   #define MAXLEN 20   int front=MAXLEN-1;//佇列初始化 int rear=MAXLEN-1;   enqueue(int q[],int x) //入隊 {   rea

問題 java程式碼實現高效率

<pre name="code" class="java">//約瑟夫問題 package com.test; public class test { public static void main(String[] args) { CycLink cycLink= n

java中代理,靜態代理,動態代理以及spring aop代理方式,實現原理統一彙總 Spring中AOP的代理方式Java動態代理CGLIB代理

若代理類在程式執行前就已經存在,那麼這種代理方式被成為 靜態代理 ,這種情況下的代理類通常都是我們在Java程式碼中定義的。 通常情況下, 靜態代理中的代理類和委託類會實現同一介面或是派生自相同的父類。 一、概述1. 什麼是代理我們大家都知道微商代理,簡單地說就是代替廠家賣商品,廠家“委託”代理為

斐波那契數列的三實現方式、迴圈、矩陣

《劍指offer》裡講到了一種斐波那契數列的 O(logN) 時間複雜度的實現,覺得挺有意思的,三種方法都記錄一下。 一、遞迴     一般來說遞迴實現的程式碼都要比迴圈要簡潔,但是效率不高,比如遞迴計算斐波那契數列第n個元素。 long long Fibonacci

猴子選大王問題解決方案

問題: 有M只猴子圍成一圈,按序每隻從1到M中的編號,打算從中選出一個大王;經過協商,決定出選大王的規則:從第一個開始迴圈報數,數到N的猴子出圈,最後剩下來的就是大王。要求:從鍵盤輸入M、N,程式設計計算哪一個編號的猴子成為大王 示例: 比如有5只猴子,從1到3報數,則選

問題的解法詳解

lang 方式 第一次 stat 位置 code 模擬 mod 想要 約瑟夫環問題的兩種解法(詳解) 題目: Josephus有過的故事:39 個猶太人與Josephus及他的朋友躲到一個洞中,39個猶太人決定寧願死也不要被敵人抓。於是決定了自殺方式,41個人排成一個

hdu4841---圓桌問題解題報告(問題---陣列,queue,vector三實現方式)

                                          &

問題的解法詳解【轉】

題目:  Josephus有過的故事:39 個猶太人與Josephus及他的朋友躲到一個洞中,39個猶太人決定寧願死也不要被敵人抓。於是決定了自殺方式,41個人排成一個圓圈,由第1個人開始報數,每報數到第3人該人就必須自殺。然後下一個重新報數,直到所有人都自殺身亡為止。

C語言,陣列實現問題方法

約瑟夫環問題:約瑟夫環是一個數學的應用問題:已知n個人(以編號1,2,3...n分別表示)圍坐在一張圓桌周圍。從編號為k的人開始報數,數到m的那個人出列;他的下一個人又從1開始報數,數到m的那個人又出列;依此規律重複下去,直到圓桌周圍的人全部出列。 第一種方法:要求將每次

用循鏈表解決問題

循環 解決 使用 end head als list output 循環條件 約瑟夫環是一個數學的應用問題:已知n個人(以編號1,2,3...n分別表示)圍坐在一張圓桌周圍。從編號為k的人開始報數,數到m的那個人出列;他的下一個人又從1開始報數,數到m的那個人又出列;依此規

解決方案

還要 print span and clas 每次 code logs led 1 #include<stdio.h> 2 /* 3 * your own thougt is always best!! 4 * 5 */ 6 int couldk

單循鏈表 解決的問題

malloc 表示 重復 printf 約瑟夫 ext std head eof 已知n個人(以編號1,2,3...n分別表示)圍坐在一張圓桌周圍。從編號為k的人開始報數,數到m的那個人出列;他的下一個人又從1開始報數,數到m的那個人又出列;依此規律重復下去,直到圓桌周圍的

用迴圈連結串列解決的問題

約瑟夫環問題簡介  約瑟夫環問題的原來描述為,設有編號為1,2,……,n的n(n>0)個人圍成一個圈,從第1個人開始報數,報到m時停止報數,報m的人出圈,再從他的下一個人起重新報數,報到m時停止報數,報m的出圈,……,如此下去,直到所有人全部出圈為止。當任意給定n和m後,設計演算法求n個人出

PHP解決的問題

//準備好41個人 $people = array(); for($i=0;$i<=40;$i++) { $people[] = $i+1; } /** * @param $people 準備好的陣列 * @param $step 每到第幾個人,會把他殺掉 * @p

關於的幾求解問題

問題描述:0,1,2......,n-1這n個數字排成一個圓圈,從數字0開始,每次從這個圓圈裡刪除第m個數字。求出這個圓圈裡最後剩下的數字。 例如:0,1,2,3,4這5個數字組成一個圓圈,從數字0開始每次刪除第三個數字,則刪除的前四個數字依次是2,0,4,1,因此最後剩下的數字是3. 解法

使用C語言單向迴圈連結串列來解決

題目描述 編號為1,2,…,n的n個人按順時針方向圍坐在一張圓桌周圍,每人持有一個密碼(正整數)。一 開始任選一個正整數m作為報數上限值,從第一個人開始按順時針方向自1開始報數,報到m時停止報數,報m的那 個人出列,將他的密碼作為新的m值,從他順時針方向的下一個人開始重新從1報數,