如何解決約瑟夫問題?

2021-09-25 09:00:09 字數 3545 閱讀 5895

1.josephu問題

問題介紹:

設編號為1,2,3...n的n個人圍坐一圈,約定編號為k(1<=k<=n)的人從1開始報數,數到m的那個人出列,它的下一位又從1開始報數,數到m的那個人出列,依次類推

如何解決約瑟夫問題?

構建環形鍊錶+處理演算法

思路:

使用乙個不帶頭結點的迴圈鍊錶來處理問題,先構成乙個有n個結點的單迴圈鍊錶,然後由k結點起從1開始計數,計到m的時候 對應結點從鍊錶中刪除,然後再從被刪除節點的下乙個從1開始計數,直到最後乙個節點刪除,演算法結束

示意圖:

k         編號為k的人開始報數

令n=5 說明有5個人

令k=1 說明從第乙個人開始報數

令m=2說明每數兩下就出圈1次

出佇列順序:2-->4-->1-->5-->3

**實現:

1.構建環形鍊錶:

*先建立第乙個節點,建立first指向該節點,並形成環狀

*後面當我們每建立乙個新的節點,就把該節點加到現有的環形鍊錶中

2.遍歷環形鍊錶

*先讓乙個輔助指標指向first

*然後通過while迴圈進行迴圈遍歷該節點,直到遍歷的下乙個為first,遍歷結束

public class josepfu 

}//建立乙個boy 表示節點

class boy

public void setno(int no)

public boy getnext()

public void setnext(boy next)

private boy next;//指向下乙個節點,預設為null

public boy(int no)

}//建立乙個環形的單向鍊錶

class circlesinglelinkedlist

//建立輔助節點,幫助構建環形鍊錶

boy curboy=null;

//使用for建立環形鍊錶

for(int i=1;i<=nums;i++)else}}

//遍歷當前的環形鍊錶

public void showboy()

//因為first不能動,因此使用輔助指標完成遍歷

boy curboy=first;

while(true)else}}

}

4.處理演算法如何根據使用者的輸入,如何生成乙個小孩出圈的順序?

k         編號為k的人開始報數

令n=5 說明有5個人

令k=1 說明從第乙個人開始報數

令m=2說明每數兩下就出圈1次

*建立乙個輔助指標helper實現指向環形鍊錶的最後乙個節點,當小孩報數前,移動first和helper指標到合適的位置(移動k-1次)

*小孩報數後,讓first和helper同時移動m-1次,然後開始考慮當前節點出圈(first=first.next; helper.next=first;)

**實現:

/**

* startno:表示從第幾個小孩開始數數

* countnum:表示數幾下

* nums:表示最初有多少小孩在圈中

*/public void countboy(int startno, int countnum, int nums)

//輔助指標,幫助完成小孩出圈

boy helper = first;

//1.讓helper指向最後乙個節點

while (true)

helper = helper.getnext();

}//2.小孩報數前,先讓first和helper移動startno-1次

for (int j = 0; j < startno - 1; j++)

//當小孩報數時,讓first和helper指標同時向後移動countnum-1次,然後出圈

while (true)

//first和helper指標同時向後移動countnum-1次.然後出圈

for(int j=0;j

處理約瑟夫問題完整**:

public class josepfu

}//建立乙個boy 表示節點

class boy

public void setno(int no)

public boy getnext()

public void setnext(boy next)

private boy next;//指向下乙個節點,預設為null

public boy(int no)

}//建立乙個環形的單向鍊錶

class circlesinglelinkedlist

//建立輔助節點,幫助構建環形鍊錶

boy curboy = null;

//使用for建立環形鍊錶

for (int i = 1; i <= nums; i++) else }}

//遍歷當前的環形鍊錶

public void showboy()

//因為first不能動,因此使用輔助指標完成遍歷

boy curboy = first;

while (true) else }}

//根據使用者的輸入,計算出圈順序

/*** startno:表示從第幾個小孩開始數數

* countnum:表示數幾下

* nums:表示最初有多少小孩在圈中

*/public void countboy(int startno, int countnum, int nums)

//輔助指標,幫助完成小孩出圈

boy helper = first;

//1.讓helper指向最後乙個節點

while (true)

helper = helper.getnext();

}//2.小孩報數前,先讓first和helper移動startno-1次

for (int j = 0; j < startno - 1; j++)

//當小孩報數時,讓first和helper指標同時向後移動countnum-1次,然後出圈

while (true)

//first和helper指標同時向後移動countnum-1次.然後出圈

如何解決藍屏問題

第一步 公升級筆記本bios 一般說來筆記本在出廠的時候很可能設計上存在某些的瑕疵,而廠商通常會採用公升級bios的方法來解決這些bug。如果我們在使用筆記本腦的過程中遇到了藍屏的情況,那麼我們可以採取公升級bios的辦法來解決藍屏的故障。第二步 正確安裝硬體驅動 在重新整理了bios以後,部分筆記...

如何解決fpga high fanout問題

fanout,即扇出,指模組直接呼叫的下級模組的個數,如果這個數值過大的話,在fpga直接表現為net delay較大,不利於時序收斂。因此,在寫 時應盡量避免高扇出的情況。但是,在某些特殊情況下,受到整體結構設計的需要或者無法修改 的限制,則需要通過其它優化手段解決高扇出帶來的問題。以下就介紹三個...

如何解決fpga high fanout問題

fanout,即扇出,指模組直接呼叫的下級模組的個數,如果這個數值過大的話,在fpga直接表現為net delay較大,不利於時序收斂。因此,在寫 時應盡量避免高扇出的情況。但是,在某些特殊情況下,受到整體結構設計的需要或者無法修改 的限制,則需要通過其它優化手段解決高扇出帶來的問題。以下就介紹三個...