C語言處理約瑟夫問題(丟手絹)
阿新 • • 發佈:2019-02-11
(部分經驗援引自其他人)
問題描述:
在羅馬人佔領喬塔帕特後,39 個猶太人與Josephus及他的朋友躲到一個洞中,39個猶太人決定寧願死也不要被敵人抓到,於是決定了一個自殺方式,41個人排成一個圓圈,由第1個人開始報數,每報數到第3人該人就必須自殺,然後再由下一個重新報數,直到所有人都自殺身亡為止。
在此,我們對該問題進行通用化,假定有n個人圍成一個圈,按順序進行拍號。從第一個人開始報數,當報到k時,這個人就要退出,剩下的人接著依次進行報數,直至最後僅剩一個人。問最後那個人是原來的第幾號?
利用陣列和指標解決該問題時,該問題的解決思路為:首先我將每一個人在陣列中的值0,當其編號除以K的餘數為0時,將該人在陣列中的值賦予1,這樣在迴圈過程中,在此遇得到該人時,就直接跳過(相當於該人退出)。原始碼如下:
void find(int *p,int n,int t) { int call_n=0,out_n=0,*q; q=p+n; while(1) { if(*p==0) { if(out_n==n-1)break;//限定只剩一個人時結束迴圈 call_n++; call_n%=t;//求餘 if(call_n==0) { *p=1; out_n++; } } p++; if(p==q)p=(q-n);//當迴圈到陣列末端時,重新迴圈 } printf("最後剩餘編號%d\n",p+1-a); } int main(int argc, char *argv[]) { int n,call_n=0,out_n=0,*p,t; printf("請輸入人數:\n");//輸入人數 scanf("%d",&n); printf("請輸入到幾退出\n");//數到t時退出 scanf("%d",&t); int a[1000]={0}; find(a,n,t); }