據說著名猶太曆史學家 Josephus有過以下的故事:在羅馬人佔領喬塔帕特後,39 個猶太人與Josephus及他的朋友躲到一個洞中,39個猶太人決定寧願死也不要被敵人抓到,於是決定了一個自殺方式,41個人排成一個圓圈,由第1個人開始報數,每報數到第3人該人就必須自殺,然後再由下一個重新報數,直到所有人都自殺身亡為止。然而Josephus 和他的朋友並不想遵從,Josephus要他的朋友先假裝遵從,他將朋友與自己安排在第16個與第31個位置,於是逃過了這場死亡遊戲
/* * 內容:約瑟夫問題(Josephus Problem) * 時間:2/11/2013 */ #include <stdio.h> #define NUMBER 41 #define DEATH 3 //第一種方法,記錄每個人的死亡順序 void firstFunction(int josephus[]) { int count = 1;//記錄自殺人的順序 int flag = 0;//標記報數的人數 int pos = -1; while (count <= NUMBER) {do{pos = (pos + 1) % NUMBER;//環狀處理if (josephus[pos] == 0){++flag;}if (flag == DEATH) //判斷是否等於DEATH,等於DEATH則代表當前這個人要自殺{josephus[pos] = count;//將這個人是第幾個自殺的記錄到這個人這裡 ++count;//此時有人掛了,則自增1flag = 0;//重設 break;} }while(true); }printf ("第一種解決辦法的Josephus Problem每個人的自殺順序為: \n\n"); for (int i = 0; i < NUMBER; ++i) {printf ("第%d個人的自殺順序為:%d\t", (i+1), josephus[i]);if ( (i%3) == 0 ){printf("\n");}}printf ("\n\n\n"); } //第二種方法,記錄人數死亡的順序 void secondFunction(int josephus[]) { int order[NUMBER] = {0};//記錄自殺順序 int flag = 0;//標記報數的人數 int count = 0;//表示數組的下標 int pos = -1; while (count < NUMBER) {do{pos = (pos + 1) % NUMBER;//環狀處理if (josephus[pos] == 0){++flag;}if (flag == DEATH) //判斷是否等於DEATH,等於DEATH則代表當前這個人要自殺{josephus[pos] = 1;//將這個人是第幾個自殺的記錄到這個人這裡 order[count] = pos+1;//數組下標是從0開始算起的,所以要加1來表示人所在的位置 ++count;flag = 0;//重設 break;} }while(true); }printf ("第二種解決辦法的Josephus Problem自殺順序為: \n");for (int i = 0; i < NUMBER; ++i){printf("第%d個自殺的人的位置是:%d ", (i+1), order[i]);if ( (i%3) == 0 ){printf("\n");}}printf("\n"); } int main() { int firstPeople[NUMBER] = {0}; //初始化數組,數組的下標代表的人的編號firstFunction(firstPeople);int secondPeople[NUMBER] = {0};secondFunction(secondPeople);return 1; }