约瑟夫问题

来源:互联网 发布:淘宝开店书籍推荐 编辑:程序博客网 时间:2024/06/01 08:17

据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从。首先从一个人开始,越过k-2个人(因为第一个人已经被越过),并杀掉第k个人。接着,再越过k-1个人,并杀掉第k个人。这个过程沿着圆圈一直进行,直到最终只剩下一个人留下,这个人就可以继续活着。问题是,给定了和,一开始要站在什么地方才能避免被处决?Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。


约瑟夫问题就这样诞生了,网上关于约瑟夫问题的代码很多,但是有句话说的好:纸上得来终觉浅,绝知此事要躬行。自己写了一个,虽然不是很好,但起码把问题给解决了,菜鸟一个,希望高手看到后多加指点。

代码如下:


#include<malloc.h>#include<stdio.h>#define LEN sizeof(struct student)#define NULL 0struct student{int nom;struct student *next;};int n;                                           //全局变量n表示链表总结点数 struct student *creat()                 //创建一个环形链表 ,即n个人围成一圈,编号依次是1,2,3........n{int i;struct student *p1,*p2;p1=(struct student *)malloc(LEN);p1->next=NULL;p1->nom=NULL;struct student *head;for(i=1;i<=n;i++){if(i==1){  p1->nom=i;  head=p1;  p2=(struct student *)malloc(LEN);  p1->next=p2;  p2->next=NULL;  p1=p2;}else{if(i!=n){   p1->nom=i;   p2=(struct student *)malloc(LEN);   p1->next=p2;   p2->next=NULL;   p1=p2;}    else{p1->nom=i;p1->next=head;}}}      return head;}void del(int m1,int m2 )                           //第m1个人从1开始数起,数到m2,出列 ,然后从下一个人开始数...........直到所有人出列{struct student *p;struct student *m;int i,k,j,h;m=creat();for(j=1;j<m1;j++){m=m->next;}for(k=1;k<=n;k++){              for(i=1;i<=m2;i++) {m=m->next;if(i==(m2-2)){ p=m;     }    if(i==(m2-1))   {   p->next=m->next;  printf("出列:%d\n",m->nom);   } } }}int main(){   int c,d;  printf("请输入n,c,d:");                                           //总人数n,从编号为c的人从1开始数,数到d的人出列,下一个人再从1开始数,往后以此类推  scanf("%d%d%d",&n,&c,&d);  del(c,d);}


运行结果:




编号为16和31的最后出列,Josephus真的很聪明大笑

0 0
原创粉丝点击