一个约瑟夫环问题

 

一个约瑟夫环问题

问题开始: 罗马人攻占了乔塔帕特,41个人藏在一个山洞躲过了这场浩劫。这41个人中,包括历史学家Josephus(约瑟夫)和特的一个朋友。剩余的39个人为了表示不向罗马人屈服,决定集体自杀。大家决定了一个自杀方案,所有这41个人围成一个圆圈,由第一个人开始顺时针报数,每报数为3的人就立刻自杀,然再由下一个重新开始报数,仍然是每报数为3的人立刻就自杀,。。。。,直到所有的人都自杀身亡位置。 约瑟夫和他的朋友并不想自杀,于是约瑟夫想到一个计策,他们两个同样参与到自杀的方案中,但是最后却躲过了自杀。请问,他们是怎么做到的? 先分析一下约瑟夫和他朋友想要躲过自杀,那么自杀到嘴壶一轮剩下三个人,且约瑟夫和他的朋友应该位于1和2的位置,这样就能躲过自杀, 首先将41个人排成一个环,内圈按顺时针的最初编号,外圈为每个人数到3的顺序,就是约瑟夫环号,如下图 

 

 

 

 

下面是这个问题的代码实现,(java)

 

 

 

1package neuq.chao;

 2 
 3 public class Josephus {
 4     static final int Num = 41;
 5     static final int KillMan =3;
 6     static void josephus(int alive){
 7         //alive为要存活的人的个数
 8         int man[] = new int[Num];     //声明一个数组
 9         int pose = -1;                //指针
10         int i = 0;                      
11         int count = 1;
12         while(count<=Num){
13             do{
14                 pose = (pose+1)%Num;
15                 if(man[pose]==0){            //等于0没有自杀
16                     i++;
17                     if(i==KillMan){            //数到3的人自杀
18                         i=0;
19                         break;
20                     }
21                 }
22             }while(true);
23             man[pose] = count;
24             System.out.printf("第%2d个自杀的人约瑟夫环号为:%2d",man[pose],pose+1);
25             if(count%2==1){                
26                 System.out.printf("->");
27             }
28             else{
29                 System.out.printf("->\n");     //控制输出格式
30             }
31             count++;                        //自杀人加1
32         }
33         System.out.println("/n");
34         System.out.printf("这%d需要存活的人的初始序号应排列在以下序号:\n",alive );
35         alive = Num - alive;
36         for(i=0;i<Num;i++){
37             if(man[i]>alive){               //最后两个自杀的人存活
38                 System.out.printf("初始编号为:%d", i+1);
39             }
40         }
41         System.out.printf("\n");
42     }
43     public static void main(String args[]){
44         josephus(2);                      //演示
45     }
46 }

向以上问题我们可以统归为约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。

只要对上述代码稍加修改即可形成对这一问题的统一解法

 

posted @ 2015-03-31 17:13  孤光一点莹  阅读(470)  评论(0编辑  收藏  举报