另類約瑟夫問題

2021-07-25 22:50:49 字數 1576 閱讀 5443

總共有 n 個人編號為 1 號到 n 號(每個人的編號一直不變),一開始只取 1 號到 m 號沿順時針圍成一圈(臉都對著圓心)。同樣是依次報數,當輪到報數為 k 的人時,如果此人的編號為奇數,則將剩餘的人中編號最小的人插入此人右側,如果此人的編號為偶數,則將剩餘的人中編號最小的人插入此人左側。並從報數為 k 的人左側開始重新開始重複此過程。當圍成乙個 n 個人的圈後,繼續從報數為 k 的人左側重新開始沿順時針報數,當有人再次報數為 k 時,此人出列。繼續從出列的人的左側重新開始重複此過程。直到圍成圈的人數再次為 m 時停止。

問: 最後留下的 m 個人中,有多少來自一開始取的 m 個人。

注: 鍊錶中當 n 非常大時,考慮到時間複雜度,k 可以取 k≪n。

示例: 假設 n=6, m=4, k=2。則一開始取的人編號分別 1,2,3,4 的人圍成一圈。然後從 1 開始報兩個數。 2 為偶數,則圓圈中編號為 2 的人左側位置加乙個 5,圓圈的順序變為: 1,2,5,3,4。 又從 5 開始重新報數,報 2 的人為 3 號,則往其圓圈中的右側位置加乙個 6。圓圈順序變為 1,2,5,6,3,4。 此時 6 人全部在圓圈中,繼續從剛剛的 3 號的下一位 4 號報數,報 2 的人為 1 號,則 1 號出列。圓圈順序變為 2,5,6,3,4,繼續從 1 號下一位開始報數,下一次報 2 的為 5 號,則 5 號出列。則圓圈的順序變為 2,6,3,4。其中 2,3,4 號來自於一開始取的 1,2,3,4 中,所以答案為 3。

按照 n m k 的順序輸入引數,其中 n 為總人數,m 為初始的選取人數,k 是每次報數的個數。

輸出最後剩餘 m 人中屬於最開始 m 人的個數

6 4 2

一道簡單的迴圈鍊錶應用題,注意處理好新增表頭時指標的判斷。

#include

using namespace std;

struct node;

struct list;

void initlist(list &l)

void einsert(node *&p,node *&

q,int i)

void oinsert(node *&p,node *&

q,int i)

int main()

node *p=circle.head,*q=circle.head->next;

for(int i=m+1;i<=n;i++)

p=q;

q=p->next;

if(q==circle.head)

}if(q->num % 2==0)

einsert(p,q,i);

else

oinsert(p,q,i);

}if(q==circle.head)

for(int i=n;i>m;i--)

}p->next=q->next;

delete

q; q=p->next;

if(q==circle.head)

}node *seek=circle.head->next;

int remain=0;

while(seek!=circle.head)

coutcout0;}

約瑟夫問題 約瑟夫環

約瑟夫 問題 有時也稱為約瑟夫斯置換,是乙個出現在電腦科學和數學中的問題。在計算機程式設計的演算法中,類似問題又稱為約瑟夫環。又稱 丟手絹問題 據說著名猶太歷史學家 josephus有過以下的故事 在羅馬人占領喬塔帕特後,39 個猶太人與josephus及他的朋友躲到乙個洞中,39個猶太人決定寧願死...

約瑟夫問題 約瑟夫環

約瑟夫問題 有時也稱為約瑟夫斯置換,是乙個出現在電腦科學和數學中的問題。在計算機程式設計的演算法中,類似問題又稱為約瑟夫環。又稱 丟手絹問題 據說著名猶太歷史學家 josephus有過以下的故事 在羅馬人占領喬塔帕特後,39 個猶太人與josephus及他的朋友躲到乙個洞中,39個猶太人決定寧願死也...

約瑟夫問題

這是17世紀的法國數學家加斯帕在 數目的遊戲問題 中講的乙個故事 15個教徒和15 個非教徒在深海上遇險,必須將一半的人投入海中,其餘的人才能倖免於難,於是想了乙個辦法 30個人圍成一圓圈,從第乙個人開始依次報數,每數到第九個人就將他扔入大海,如此迴圈進行直到僅餘15個人為止。問怎樣排法,才能使每次...