3 參考**
選大王時間限制 1000 ms 記憶體限制 32768 kb **長度限制 100 kb 判斷程式 standard (來自 小小)
題目描述
有n只猴子,按順時針方向圍成一圈選大王(編號從1到n),從第1號開始報數,一直數到m,數到m的猴子退出圈外,剩下的猴子再接著從 1 開始報數。就這樣,直到圈內只剩下乙隻猴子時,這個猴子就是猴王。
現在告訴你 n 和 m,請幫忙求出哪乙隻猴子能當大王。
輸入描述:
輸入包含多組資料。
每組資料報含兩個正整數 n 和m(1≤ m < n ≤ 10000)。
輸出描述:
對應每一組輸入,輸出猴王的編號 i(1≤i≤n)。
輸入例子:
7 38 3
輸出例子:47
求最後剩下的猴子編號
約瑟夫問題
問題來歷
據說著名***歷史學家 josephus有過以下的故事:在羅馬人占領喬塔帕特後,39 個***人與josephus及他的朋友躲到乙個洞中,39個***人決定寧願死也不要被敵人抓到,於是決定了乙個***方式,41個人排成乙個圓圈,由第1個人開始報數,每報數到第3人該人就必須***,然後再由下乙個重新報數,直到所有人都***身亡為止。然而josephus 和他的朋友並不想遵從。首先從乙個人開始,越過k-2個人(因為第乙個人已經被越過),並殺掉第k個人。接著,再越過k-1個人,並殺掉第k個人。這個過程沿著圓圈一直進行,直到最終只剩下乙個人留下,這個人就可以繼續活著。問題是,給定了人數總和,一開始要站在什麼地方才能避免被處決?josephus要他的朋友先假裝遵從,他將朋友與自己安排在第16個與第31個位置,於是逃過了這場死亡遊戲。
直接模擬
假設 對於n,m 已知 k 是當前需要***的人,當前序列為
0,1,… ,k-1, k , k+1, … , n-1
那麼剩下的人分別為
0,1,… ,k-1, k+1, … , n-1
接下來需要從 k+1 處開始報數,不妨對 k 以前的數 +n, 即:
n, n+1, … , n+k-1, k+1, … , n-1
按照報數順序排列:
k+1, … , n,n+1, … , n+k-1
這個序列可看出,僅比正常序列 0,1,… , n-2 多了 k+1
所以有:
假設 josephus(n,m)是序列 0,1,… , n-1迴圈報數最終剩下的人,
則 josephus(n-1,m)為序列 0,1,… , n-2迴圈報數最終剩下的人
josephus(n,m)= josephus(n-1,m)+k+1
考慮到運用上述公式時,是對 n,m序列 對k之前的數+n得到的,
因此應當修正為
josephus
(n,m)
=( josephus
(n-1
,m)+k+
1)%n
如此即可還原到原始序列。
又因為對於任意 n,m ,初始k值我們是可以求解得到的
k=
(m%n)
-1
所以
josephus
(n,m)
=( josephus
(n-1
,m)+
(m%n))%n
josephus
(n,m)
=( josephus
(n-1
,m)+m)%n
至此已形成遞迴
遞迴截至條件也顯而易見
josephus(1
,m)=
0
注意
此解法針對的是 0, 1, 2, … , n-1的序列,
但約瑟夫環一般是從1 開始的,即 1, 2, … , n
所以我們利用 josephus(n,m)求出的結果要 +1才是最終結果。
參考()
#include
#include
using std::vector;
vector<
int> a;
intmain
(int argc,
char
const
*ar**)
else
int pos = m -1;
while
(a.size()
>1)
int tsize =
(int
) a.
size()
; pos = pos % tsize;
}printf
("%d\n"
,a[0])
; a.
clear()
;}}return0;
}
#include
intjosephusrecursive
(int n,
int m)
return
(josephusrecursive
(n-1
,m)+m)
%n;}
intmain
(int argc,
char
const
*ar**)
// /*
// * 此解法針對的是 0, 1, 2, ... , n-1的序列,
//但約瑟夫環一般是從1 開始的,即 1, 2, ... , n
//所以我們利用 josephus(n,m)求出的結果要 +1才是最終結果。
// */
printf
("%d\n"
, r +1)
;}return0;
}
約瑟夫問題(猴子選大王)
問題描述 約瑟夫問題 有 只猴子,按順時針方向圍成一圈選大王 編號從 到 從第 號開始報數,一直數到 數到 的猴子退出圈外,剩下的猴子再接著從1 開始報數。就這樣,直到圈內只剩下乙隻猴子時,這個猴子就是猴王,程式設計求輸入 後,輸出最後猴王的編號。輸入資料 每行是用空格分開的兩個整數,第乙個是 n,...
猴子選大王 約瑟夫問題
例題描述 由m只猴子圍成一圈,從1到m進行編號,打算從中選出乙個大王,經過協商,決定選出大王的規則 從第乙個開始迴圈報數,數到n的猴子出圈,下乙個猴子從1開始報數。輸入樣例 3 2 輸出樣例 3方法一 模擬法 include using namespace std define max 100 lo...
約瑟夫問題,猴子選大王
描述 約瑟夫問題 有 只猴子,按順時針方向圍成一圈選大王 編號從 到 從第 號開始報數,一直數到 數到 的猴子退出圈外,剩下的猴子再接著從1開始報數。就這樣,直到圈內只剩下乙隻猴子時,這個猴子就是猴王,程式設計求輸入 後,輸出最後猴王的編號。輸入每行是用空格分開的兩個整數,第乙個是 n,第二個是 m...