n個人圍成乙個圈,每個人分別標註為1、2、...、n,要求從1號從1開始報數,報到k的人出圈,接著下乙個人又從1開始報數,如此迴圈,直到只剩最後乙個人時,該人即為勝利者。例如當n=10,k=4時,依次出列的人分別為4、8、2、7、3、10,9、1、6、5,則5號位置的人為勝利者。給定n個人,請你程式設計計算出最後勝利者標號數。(要求用單迴圈鍊錶完成。)
題目就是這樣了,要求輸入兩個整數,輸出勝利者(最後乙個出圈)。題目要求用鍊錶完成,除了鍊錶方法外,還有陣列和數學公式來解決,一共三種。
首先是最常見的陣列演算法,首先定義乙個一維整形陣列a[size],並初始化為0,作為模擬所有人以及是否出圈;用乙個整形數作為報數count的編號,當等於k時,初始化;用乙個整形數m表示剩下的人數。演算法原理如下:當count等於k時,將a[i](i是當前報數人的編號)賦值為1,並初始化count,剩餘人數m自減1,報數繼續。當遇到a[i]等於1時,直接跳過,讓下乙個人報當前的數。當m等於1時,表示只剩下最後乙個人,報數結束。
操作如下
關鍵**如下(c):
接下來就是對數學演算法的**,陣列是直接改變「報數人」的狀態,而這個演算法是改變「報數人」邏輯上的連線關係。當「報數人」出圈後,將下乙個人的編號改為0,然後依次編號,當只剩最後乙個人時,他的編號就是0,通過倒推,可以得知這個人的編號,因為是從0開始編號的,所以這個人的實際編號應加一。但是我們只是只是求最後乙個人的編號,而不是如何所有的「報數人」出圈只剩乙個人,這是沒必要的。#include#define size 1001
int main();
printf("%d", a[0]);
scanf("%d", &n);
scanf("%d", &k);
int flag = 0; //記錄最後乙個人
int m = n;
int s = 0;
while(m >= 1)else
if(s % k == 0)
s = 0;
a[i] = 1;
m--;
}} }
printf("%d", flag);
return 0;
}
「報數人」出圈大致如下:
如圖所示,n表示總人數,k表示報數的最大值,i表示剩餘人的總數,a表示最後乙個人的編號。可以看到i=5的那一行,當編號為2時,則出圈。那麼,為了重新構建新的序列,3是如何變為0的呢?不難想到,因為k=3,所以序號為3的要變為0;而0呢,是如何變為2的?因為0小於k,所以0 - k = -3,序數為負數,顯然不對。因此,但h(當前報數人的編號) - k 小於0時,應該與當前人數i相加。因為要判斷差是否小於零,可以事先讓所有的小於k的編號都加上當前總人數i,在進行求餘,就可以得到下一輪的新編號(h = h > k? h: h + i;)。那麼,這樣就可以實現報數人出圈了。但問題是如何求得最後乙個報數人的實際編號呢?
同理,根據報數人出圈的規律,可以的知最後乙個人的編號一定為0,反推就可以得到比實際編號小一的編號。就可以得到公式a = (a + k) % i。
演算法具體實現如下:
參考博文:#includeint main()
printf("%d", a + 1);
return 0;
}
最後就是鍊錶實現,鍊錶直接將報數人刪除,十分的形象。
用鍊錶實現,就得先建立,用結構體儲存編號的連線下乙個節點。便於操作,建立乙個迴圈鍊錶,採用頭插法儲存編號。
演算法具體實現如下:
#include#includestruct list;
void createlist(struct list *&head, int n)else
} p1->next = head;//首尾相連
}//void testout(struct list *head)while(p != head);
//}void deal(struct list *head, int m, int n)
p = head;
head = head->next;
while(n != 1)else
} printf("%d", head->data);
free(head);
}int main()
約瑟夫問題的實現 swustoj
約瑟夫問題的實現 2000 ms 65535 kb 2662 8037 n個人圍成乙個圈,每個人分別標註為1 2 n,要求從1號從1開始報數,報到k的人出圈,接著下乙個人又從1開始報數,如此迴圈,直到只剩最後乙個人時,該人即為勝利者。例如當n 10,k 4時,依次出列的人分別為4 8 2 7 3 1...
SWUSTOJ 1027 舞伴問題
源 假設在週末舞會上,男士們和女士們進入舞廳時,各自排成一隊。跳舞開始時,依次從男隊和女隊的隊頭上各出一人配成舞伴。若兩隊初始人數不相同,則較長的那一隊中未配對者等待下一輪舞曲。要求編寫程式實現舞伴問題。輸入一共5行,第一行是男生人數m 第二行依次是男生的姓名 第三行是女士的人數n 第四行依次是女士...
約瑟夫問題 約瑟夫環
約瑟夫 問題 有時也稱為約瑟夫斯置換,是乙個出現在電腦科學和數學中的問題。在計算機程式設計的演算法中,類似問題又稱為約瑟夫環。又稱 丟手絹問題 據說著名猶太歷史學家 josephus有過以下的故事 在羅馬人占領喬塔帕特後,39 個猶太人與josephus及他的朋友躲到乙個洞中,39個猶太人決定寧願死...