(部分经验援引自其他人)
问题描述:
在罗马人占领乔塔帕特后,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);
}