H On簡結 思路超清晰的解釋約瑟夫環問題

2021-10-03 07:31:35 字數 3345 閱讀 9703

在一年半前還是個新生,第一次接觸專業的程式設計教育的我刷題刷的很起勁,經典的猴子選大王問題就是在那時候遇到的,那時候我花了好久,用陣列加判斷實現了模擬選人,最終做出來了這道題。

如今已經熟練了掌握各種容器,對程式設計的理解也不可同日而語,但模擬已經不能滿足如今的需要了。

好久以前老師曾助教新生時發現乙個孩子用了 「公式推導法」 卻說不出個所以然,於是讓我們來解釋,當時我絞盡腦汁沒有想明白,最後有幾個慧根靈光的同學說了說,感覺沒懂,於是不再深究。

直到前幾天做題又遇到了這個題,模擬時間超限,公式法又不會,於是等到比賽結束,開始用心的研究【約瑟夫環】了。

演算法講解

**展示

變 k 講解

推薦題目

鳴謝文章

基礎題意

像以上這些都是可以用約瑟夫環來解決的例題,這裡我只列了三個我想得起來的。

第乙個是基礎,第二個是應用,第三個是推廣。

思路簡介

這一類的題模擬的方法就不說了,基本上往後做 acm 用模擬肯定 tle 。

思路就是:【例如 10 只猴子裡選大王

具體怎麼轉換,接下來我們詳細講解一下轉換方式

首先搞清 10 個猴去掉 1 個怎麼變成 9 隻猴

我們先假設猴子有兩個屬性:編號位置,簡單的栗子,一開始編號和位置是對應的

第一輪選出 2 號:01

2345

6789

第二次選出 5 號:78

0123

456第三次選出 8 號:45

6701

23第四次選出 1 號:12

3456

0第五次選出 6 號:50

1234

第六次選出 0 號:23

401第七次選出 7 號:01

23第八次選出 4 號:12

0第九次選出 9 號:10

最終結果是 3 號:

0

可以看到每次都選 3 選 3 的,雖然出隊的猴的編號不一樣,但是對於新佇列除去的一定是站在 2 號位置的猴。

這就是我們說的:10 個猴去掉乙個,題目就變成從 9 個猴裡選結果【有點遞迴的意思

要注意一點,實際上程式裡的編號並不是1 ~ n而是0 ~ n-1。因為我們在往後推移的時候有可能會超出人數,因此要對人數取餘,而n 的餘數是 0 ~ n-1因此如果用1 ~ n來推算會出錯,結果需要+1,之後看**的時候還會再次說明此事

其次搞清每一輪的結果之間的關係

k是乙個數,每當報數報到 k 就把這個人踢出去,這裡先宣告一下 k ,現在先以 3 為例。

觀察上面的栗子,最開始的序列是

序列 a:01

2345

6789

之後 2 號踢出去之後,因為接下來假裝還是從 0 開始報數,所以 3 號變 0 號

序列 b:78

0123

456

我們會發現,序列 b 中的任何一 個號 i 都滿足乙個式子(bi + 3) % a的長度 = a中對應的數

幾個栗子:

(7+

3)%10

=0(0

+3)%

10=3(

4+3)

%10=7

同理:

第二次選出 5 號:78

0123

456第三次選出 8 號:45

6701

23(7

+3)%

9=1(

5+3)

&9=8

第八次選出 4 號:12

0第九次選出 9 號:10

(0+3

)%3=

0(1+

3)%3

=1

我相信到此為止,大家都了然了,既然公式有了,那還說啥?迴圈就完事了

這裡還要再說一句,因為這個思路從上到下的標號一直在變,公式也是從下往上推算的,因此迴圈的時候也是從求 2 個數的結果求 n 個數的結果。你問 n = 1 的時候怎麼辦?結果不是已經出來了嗎 = =

r 的初始值是 0 ,因為求 1 個猴的話結果直接就是第乙個 - 0 。每次迴圈求的都是答案對應在上一層的編號推算到最後就得到最後的編號了。如果編號是1 ~ n的話返回的結果就要+1

#include

using

namespace std;

intjo

(int n,

int k)

intmain()

其實我對遞迴的寫法還是挺喜歡的:jo 級函式

int

jojo

(int n,

int k)

我們知道,k 是乙個關鍵數,每當報數報到 k 的時候就處理,那麼這個關鍵數如果改變了怎麼辦呢。只要我們搞清楚每一輪對應的關鍵數是多少就好。

上面說過的第三個栗子:第一輪殺 報 1 的,第二輪殺 報 2 的 . . .這時候我們只需要讓 k 的值變起來就好了

注意:n 個人的時候,k 是 1 ,n 越來越少的時候 k 越來越大,所以這個每一輪對應的 k 值一定要想清楚

#include

using

namespace std;

intjo

(int n,

int k)

intmain()

同樣給出遞迴的方式,各位可以嘗試自己理解一下

int

jojo

(int n,

int k)

國王遊戲

我看了好多將約瑟夫環的文章,大都講的不明不白,有的甚至直接給個**。直到看了這篇文章,裡面有把各階段列出來,讓我茅塞頓開。就像我學線段樹那會,有時候對不好理解的**,把每一步改變都列出來對理解和解釋原理都有很大的幫助。請看 -----> 秒懂約瑟夫環

因為猹的小站真的還挺可的,所以那邊更新的也比較勤奮,感謝關注~我會努力的(ง •_•)ง

架構高併發系統簡結

第一部分 建設 提公升效能三步 1 分離應用與資料庫 2 快取 3 應用集群與資料庫集群 需要負載均衡 4 現實問題 分離資料的讀和寫 需要同步工具,分表 5 大型分布式應用架構 第二部分 應急 當已有的應用不能滿足效能需求時 1 重新架構系統 複雜 2 在既有架構下進行擴充套件 即scale ou...

java縱向知識 volatile簡 結

volatile 揮發性 1,保證可見性 2,禁止指令重排序 一定程度保證有序性 3,並不能保證原子性 lock字首指令 記憶體屏障 記憶體柵欄 具體使用條件 1 對變數的寫操作不依賴於當前值 2 該變數沒有包含在具有其他變數的不變式中 某些情況效能優於synchronized 但是不能替代之。使程...

排序 思路簡析(一)

本篇文章總結一下最近學習的排序演算法,提煉出其思想及不同之處。有歸併排序,快速排序,堆排序以及氣泡排序 採用兩兩分解和歸併的策略簡單易行,這樣的歸併排序稱為2 路歸併排序。歸併排序的實現 public static void sort int arr public static void merge...