1. 程式人生 > >C語言處理約瑟夫問題(丟手絹)

C語言處理約瑟夫問題(丟手絹)

(部分經驗援引自其他人)

問題描述:

     在羅馬人佔領喬塔帕特後,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);
}