算法12---约瑟夫环问题

算法12---约瑟夫环问题

1 首先我们来解决一个约瑟夫环的问题,再慢慢的深入。
 
问题描述:
罗马人攻占了桥塔帕克,41个人躲在一个山洞中,逃过了这场浩劫。这41人中,包括历史学家约瑟夫和他的一个朋友。剩余的39人为了表示不想屈服罗马人,决定集体自杀。大家想到了一个自杀方案,这41个人围城一个圆圈,由第一个人开始顺时针报数,每报数为3的人就立刻自杀。然后再由下一个人重新开始报数,仍然是每报数为3的人自杀,。。。。,直到所有的人都自杀身亡;
约瑟夫和他的朋友不想自杀,于是约瑟夫想到了一个计策,他们两个同样的参与到自杀方案中,但是最后却躲过了自杀,请问,他是怎么做到的?
 
 1 #include <String.h>
 2 #include <stdio.h>
 3 #include <malloc.h>
 4 
 5 
 6 #define Num 41
 7 #define killman 3
 8 
 9 void josephus(int alive)
10 {
11     int man[Num]={0};
12     int count=1;
13     int i=0;
14     int pos=-1;
15     while(count<=Num)
16     {
17         do
18         {
19             pos=(pos+1)%Num;//环处理
20             if (man[pos]==0)
21             {
22                 i++;
23             }
24             if (i==killman)
25             {
26                 i=0;
27                 break;
28             }   
29         }while(1);
30         man[pos]=count;
31         printf("the %2d people die! the number of josephus is %2d
",pos+1,man[pos]);
32 
33         count++;
34     }
35     printf("the %d man who want to live should be in the number of :
",alive );
36     alive=Num-alive;
37     for (int i = 0; i < Num; i++)
38     {
39         if (man[i]>alive)
40         {
41             printf("init number:%d.josephus number:%d
",i+1,man[i]);
42         }
43     }
44     printf("
");
45 }
46 
47 
48 int  main()
49 {
50     int alive;
51     printf("the solve of josephus!
");
52     printf("the number fo people want to live:");
53     scanf("%d",&alive);
54     josephus(alive);
55     return 0;
56 }
 
 
2 我们就上面的问题引出josephus排序问题;
就是对任意输入的人数,决定自杀的个数,输出自杀的顺序;
 
 1 #include <String.h>
 2 #include <stdio.h>
 3 #include <malloc.h>
 4 
 5 
 6 #define Num 41
 7 #define killman 4
 8 
 9 void josephus_sort()
10 {
11     int man[Num]={0};
12     int count=1;
13     int i=0;
14     int pos=-1;
15     while(count<=Num)
16     {
17         do
18         {
19             pos=(pos+1)%Num;//环处理
20             if (man[pos]==0)
21             {
22                 i++;
23             }
24             if (i==killman)
25             {
26                 i=0;
27                 break;
28             }   
29         }while(1);
30         man[pos]=count;
31         printf("the %2d people die! the number of josephus is %2d
",pos+1,man[pos]);
32 
33         count++;
34     }
35 }
36 
37 
38 
39 int  main(void)
40 {
41 
42     printf("the solve of josephus sort!
");
43 
44     josephus_sort();
45     return 0;
46 }
 
3 现在接着上面的问题,升级一下:n个人坐成一个圈,现在每个人都拿一个随机写有数字的字条,游戏开始,任选一个数字m。从第一个人开始进行,按照编号重新开始报数,报道m的人出列,并且将其手中的数字作为新的出列数字。然后从下一个人开始重新从1开始报数,如此循环下去,问最后剩下来哪个人?
 1 /*
 2 由于在这里下一个决定出列的数字随机生成的,而且总的个数是可以自己定义的;
 3 在这里我们采用链表的方式来解答。
 4 */
 5 
 6 
 7 #include <string.h>
 8 #include <stdio.h>
 9 #include <malloc.h>
10 #include <time.h>
11 
12 #define random_len 10
13 
14 typedef struct node 
15 {
16     int number;  //游戏者编号
17     int psw;    //出列数字
18     struct node *next;        //指针域,指向下一个节点
19 }Lnode,*linklist; 
20 
21 
22 
23 void circleFun(linklist *list,int m)
24 {
25     linklist p,q;
26     q=p=*list;
27     while(q->next!=p)
28     {
29         q=q->next;
30     }
31     printf("the gamer out the list in this order!
");
32     while(p->next!=p)
33     {
34         for (int i = 0; i < m-1; i++)
35         {
36             q=p;
37             p=p->next;
38         }
39         q->next=p->next;
40         printf("the %d people pop,the number in his hand is %d
",p->number,p->psw );
41         m=p->psw;
42         free(p);
43         p=q->next;
44     }
45 
46     printf("the last one is %d,the number in his hand is %d 
",p->number,p->psw );
47 }
48 
49 void insertlist(linklist *list,linklist q,int number ,int psw)
50 {
51     linklist p;
52     p=(linklist)malloc(sizeof(Lnode));
53 
54     p->number=number;
55     p->psw=psw;
56     if (!*list)
57     {
58         *list=p;
59         p->next=NULL;
60     }
61     else
62     {
63         p->next=q->next;
64         q->next=p;
65     }
66 }
67 
68 
69 int  main()
70 {
71     linklist list1=NULL,q=NULL,list;
72     int num,m_number; //m_number为第一个决定出列的数字;
73     int e;
74     printf("the solve of complex josephus problem
");
75     printf("please input the number of people who join the game:");
76     scanf("%d",&num);
77     srand(time(NULL));
78     for (int i = 0; i < num; i++)
79     {
80         e=rand()%10;
81         printf("the number in %d people's hand %d 
",i+1,e);
82         insertlist(&list1,q,i+1,e);
83         if (i==0)
84         {
85             q=list1;
86         }
87         else
88             q=q->next;
89     }
90     q->next=list1;
91     list=list1;//循环链表
92 
93     printf("please input the number first input:
");
94     scanf("%d",&m_number);
95     circleFun(&list,m_number);
96     printf("
");
97     return 0;
98 }
原文地址:https://www.cnblogs.com/tao-alex/p/5919092.html