Josephus問題之Java亂彈篇
女兒生病住了幾天醫院,在我為女兒擔心的同時也使我深深的感受到醫學產業化的偉大之處,在它一切向錢看的偉大精神指導之下,醫生的工作積極性有了空前的提高,“開放思想,積極創收”成為各個醫院的熱門話題。我想大家也都發現了這種情況,那就是“沒病當成有病看的多了,小病當成大病看的多了,大病當成重病看的多了”。為了讓大家能看的起病,醫學產業化是不是到了該讓它離開,還醫院一f份聖潔的時候呢。
呵呵,說到離開,不禁讓我想到編程中的一個演算法問題:
說有10個小孩圍成一圈做遊戲,從第3個小孩起,順時針方向數,每數到第5個小孩時,該小孩離開。小孩不斷離開,圈子不斷縮小,最後剩下的一個小孩便是勝利者。大家可能會說,這不就是Josephus問題嗎。
不錯,這就是Josephus問題。那大家知道這個問題的典故嗎?
Josephus問題是建立在曆史學家Joseph ben Matthias(成為Josephus)的一個報告的基礎之上,該報告講述了他和40個士兵在公元67年被羅馬軍隊包圍期間簽定的一個自殺協定,Josephus建議每個人殺死他的鄰居,他很聰明的使自己成為這些人中的最後一個,因此獲得生還。呵呵,是不是覺得這個人很壞呢。
好了,說完這個典故,讓我們來看看Josephus問題的具體演算法實現吧。
public class Josephus {
public static void main(String args[])
{
int num = 10; //孩子總數
int interval = 5; //每次數interval個孩子,就讓該孩子離開
int []child =new int[num+1]; //孩子樹組
int []flag =new int[num+1]; //每個孩子是否在圈子的標誌,1:在 0:不在
for(int i=1;i<=num;i++){
child[i]=i;
flag[i]=1; //開始每個孩子都在圈內
System.out.println("第"+i+"個孩子的名字:"+child[i]);
}
int n = 0;
int i = 3; //從第幾個孩子開始
int j = 1; //從1開始記數
boolean noEnd = true; //是否結束的標誌
while(noEnd)
{
while(j<interval){
i =(i+1>num?1:i+1);
j+=flag[i];
}
flag[i]=0;
n++;
if(n==num){
noEnd = false;
System.out.println("第"+i+"個孩子最後勝利");
}
else{
System.out.println("第"+i+"個孩子離開");
j=0; //j達到interval時,從新開始記數
}
}
}
}
大家可以改變數字試一下,挺有意思的。查看執行結果,我總覺得這裡面似乎有什麼規律,不過我還暫時沒總結出來,如果那位朋友能總結出來,希望能讓大家知道。
最後,把下面這幾句我編的東東送給大家就算作個結束禮物吧。
醫院不是電影院,不是想看就能看。
醫院不是福利院,不是想拿就能拿,
醫院不是養老院,不是想養就能養。
醫院不是國務院,不是想進就能進。