需找新的美猴王 約瑟夫環 猴王問題

2021-05-24 21:56:03 字數 2903 閱讀 2606

曰:初時,天地混沌未開,後盤古生而開之,三皇五帝治世,世界遂分四大部洲。

東洲有山,曰花果山,天生一石猴,石破天驚,王於群猴。求藝,實菩提名之曰「悟空」。

後悟空大鬧天宮,為佛祖所困,五百載,為觀音點化,乃保唐曾取經,歷八十一難而成正果,封鬥戰勝佛,自此聞達三界,而昔日「美猴王」之名亦漸成經久之傳說……

話說,這一日,鬥戰勝佛回山省親,見花果山群猴之亂,不復昔日之繁榮,太息曰:「國不可一日無君,猴亦不可一日無王!」遂令眾猴推舉新王,然則眾猴所舉德高望重者,非一,眾也。佛略思,遂語於眾猴曰如此如此,眾猴皆贊。

試看今日之猴王,將是誰家之所得……

好吧,以上屬於我閒著蛋疼的閒扯,以後進入正文……問題描述為:

/**猴王問題。

*某森林中有n只猴子在商量猴王選舉問題,所有的猴子都想當猴王,

*因此大家商量了乙個選舉辦法如下:

*所有的猴子圍成一圈,先從第乙個猴子開始報數,報數到13的猴子就出列。

*緊接著的下乙個猴子,又從1開始進行新的一輪報數,報數到12的猴子再出列;

*依此重複下去,每一輪報數都比上一輪的報數少1,直到報數減為1之後,又從13開始報數。

*直到原列中只剩下乙個猴子為止,這個猴子就是猴王。試設計乙個程式求出猴王。

*/

約瑟夫環……
很自然地能想到,用鍊錶——環形鍊錶 比較合適。
建立乙個環形的鍊錶,每次報數報到的猴子的節點被刪除,c程式實現如下:
#include "stdafx.h"

#include

#include

/*定義結構型別*/

typedef

struct monkeymonkey;

/*** 建立乙個有n個節點的環形鍊錶

*/monkey *creatlist(

int n)

r->next = head->next;

return head;

//帶頭的鍊錶

} /**

* 誰是眾猴之王?

*/int lookfortheking(monkey *list)

for(

int i = 0; i < password -1; i++)

/*刪除p->next節點*/

monkey *temp = p->next;

p->next = temp->next;

free(temp);

}

return p->id;

} int main(

int argc,

char* argv)

示例結果:

約瑟夫環是乙個很經典的問題,最初為——

已知n個人(以編號1,2,3...n分別表示)圍坐在一張圓桌周圍。從編號為k的人開始報數,數到m的那個人出列;他的下乙個人又從1開始報數,數到m的那個人又出列;依此規律重複下去,直到圓桌周圍的人全部出列。

而變形很多,又比如如下「狐狸抓兔子」問題:

/**

* 圍繞著山頂有10個洞。乙隻兔子和乙隻狐狸各住乙個洞。 狐狸要吃兔子。

* 兔子對狐狸說:「你想吃掉我可以,但必須找到我。我就藏身於這十個洞中,

* 你從10號洞出發,先到1號洞找我,第二次隔乙個洞找我,第三次隔兩個洞找我,……,

* 以後依次類推,若能找到我,可飽餐一頓。」。

* 狐狸答應了,但是狐狸從早到晚進進出出了1000次,仍沒找到兔子。

* 請程式設計求兔子究竟躲在哪個洞裡。

*/這個問題可以在泛化一點,使山洞的個數和進進出出的次數可變,同樣用環形鍊錶求解,這次不必刪除節點,只需在每個節點(山洞)中加乙個標誌變數,標誌其是否被進出過,則c**實現:

#include "stdafx.h"

#include

#include

using

namespace std;

/*為了方便,設為全域性變數*/

int numofhole;

int times;

/*表示山洞的節點*/

typedef

struct holehole;

/***建立乙個含有numofhole個節點的鍊錶

*id值為 1 - numofhole

*/hole *creatlist()

r->next = head->next;

return head->next;

} /**

*顯示所有還存在的節點id

*/void showlist(hole *list)

hole *p = list->next;

while(p != list )

p = p->next;

}} /**

*找兔子~即執行「進進出出」的動作

*/hole *lookforrabbit(hole *list)

p->isfound = 1;

}return p;

} int main(

int argc,

char* argv)

示例結果:

有關約瑟夫環,具體見

程式設計之美2 8 找符合條件的整數

問題 任意給定乙個正整數n,求乙個最小的正整數m m 1 使得n m的十進位制表示形式裡只含有1和0。解法 由於沒有直接的數學方法能幫我們直接得到m的值,所以我們只能進行搜尋。由於相對m,乘積n m具有明顯的特徵,需要搜尋的空間要小很多,所以我們對乘積n m進行搜尋。如果n m的結果有k位,則要迴圈...

程式設計之美2 8 找符合條件的整數

這個題目是,給定乙個整數 n,需要尋找另外乙個整數 m,使得 n m 得到的結果十進位制表示中只存在1和0兩個數字。首先看到這個題目,第一思想肯定是 使 m 1,並依此遞增 m 的值,直到 n m 獲得想要的效果,但是,如果 n 很大呢,那麼計算量也是很大的,所以,我們需要尋求更好的解決辦法。書中提...

程式設計之美2 8 找符合條件的整數

書上面講的很好,程式也寫得很巧妙。最主要的一句話 只需要將10k n的結果與餘數資訊陣列裡非空的元素相加,再去模n,看看會不會出現新的餘數。include include using namespace std vectorfind number int n bigint 1 push back 0...