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);
}

猜你喜欢

转载自blog.csdn.net/yhxiaohao/article/details/79919883