/*
说明据说着名犹太历史学家Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹
太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人到,于是决定了
一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,
然后再由下一个重新报数,直到所有人都自杀身亡为止。
*/
由上可知,最后一个自杀的是在第31个位置,而倒数第二个自杀的要排在第16个位置,之前的
人都死光了,所以他们也就不知道约琴夫与他的朋友并没有遵守游戏规则了。
代码实现:
1 #include<stdio.h> 2 #include<stdlib.h> 3 #define NUM 41 //游戏人数 4 #define OUT 3 //出局序号 5 6 typedef struct Person //表示一个人的结构体 7 { 8 int num; 9 Person * next; 10 }Person; 11 12 int main() 13 { 14 int i,cnt; 15 /* 16 **先创建NUM个人,且将他们围成一圈(一个循环链表) 17 */ 18 Person *q,*p,*s,*r,* head = (Person*)malloc(sizeof(Person)); // 19 r=head; // 20 head->num = 1; // 创建第一个结点 21 for(i=2; i<=NUM ; i++) //尾插法建链表 22 { 23 s = (Person*)malloc(sizeof(Person)); 24 s->num = i; 25 r->next = s; 26 r = s; 27 } 28 r->next = head; //闭环 29 /* 30 **开始游戏 31 */ 32 printf("游戏人数是 %d 人,逢 %d 出局\n",NUM,OUT); 33 printf("出局顺序为:\n"); 34 cnt = 1; 35 p = head; 36 while(p->num != p->next->num) //是否剩下最后一个结点 37 { 38 cnt++; //先看下一个数是什么 39 if(cnt == OUT) //如果是出局的数,那么做以下处理 40 { 41 q = p->next; //先暂存下一个结点地址 42 printf("%d ",q->num); //打印即将出局的结点序号 43 p->next = p->next->next; //从循环链表中将该点去掉q指向的点去掉 44 p = p->next; //将p往后移一位 45 free(q); //释放删除的结点的内存 46 q = NULL; //将q置空 47 cnt = 1; //从p所指向的当前位置开始数 48 }else 49 p=p->next; //如果不满足出局的数,那就往后数。 50 } 51 putchar(10); //换行 52 printf("最后剩余 %d \n ",p->num); //打印最后一个数 53 free(p); //释放最后一个结点的内存 54 return 0; 55 }