一、背景故事
在罗马人占领乔塔帕特后,39个犹太人与JosephUS 以及他的朋友躲在一个山洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第一个人开始报数,每报数到第三个人,这个人就必须得自杀,然后由下一个人报数,直到所有人都自杀身亡为止,聪明的JosephUS 和它的朋友选择站在 31位和16位 ,最终他们逃过一劫。
二、解题思路
这个问题最本质其实就是循环链表的问题,围成一个圈之后,就没有结尾这就是一个典型的循环链表。一个一个顺序报数,就是链表的遍历。数到对应数字的出列,这就是循环链表的删除。
三. 代码示例
#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
int data ;
struct node * next ;
}node;
//创建n个元素的循环链,并从有效元素开始
node *create (int n)
{
node *p =NULL;
node *head;
head =(node *)malloc(sizeof(node)); //创建一个头结点
p=head;//P指向头结点
node *q;
int i =1;
if(0!=n)
{
while(i<=n)
{
q=(node*) malloc (sizeof (node));
q->data=i++; //依次加入数据
p->next =q;
p=q;//指针重新指向下一个结点
}
q->next=head->next;
}
free(head);
return q->next ;
}
int main()
{
int n=0,m=0,i;
printf("请输入总个数和循环周期");
scanf("%d , %d",&n,&m);
node *p=create(n); //创建n个内存空间
node *temp; //中间值
while(p!=p->next)
{
for(i=1;i<m-1;i++)// 循环执行一次
{
p = p->next; //移动一位
}
printf("%d->",p->next->data); //输出下一位的数据m,第一个自杀的是它
temp = p->next;
p->next =temp->next;
free(temp);//销毁空间
p=p->next;
}
printf("%d\n",p->data);//最后一个的data
return 0;
}
四、运行结果
![](https://i-blog.csdnimg.cn/blog_migrate/a351bb820456fde0b298cb5c25739fc0.png)