约瑟夫环数组简单实现

    约瑟夫环是一个很有意思的算法。大意就是:罗马人占领了乔塔帕特,41个人藏在一个山洞中躲过了这场浩劫。这41个人中,包括历史学家约瑟夫(Josephus)和他的一个朋友。剩余的31个人为了表示不想罗马人屈服,决定集体自杀。大家决定了一个自杀方案,所有这41个人围成一个圈,由第1个人开始顺时针报数,每报数为3的人立刻就自杀,然后再由下一个人重新开始报数,仍然是每报数为3的人就立刻自杀,直到所有人都自杀身亡为止。
    约瑟夫和他的朋友并不想自杀,于是约瑟夫想到了一个计策,他们两个同样参与到自杀方案中,但是最后却躲过了自杀。

    算法思路:
          41个人围成一个圈报数,数到3的人就立刻自杀。约瑟夫和朋友想活下来的话,也就是当39个人都数到3并立刻自杀后,约瑟夫和朋友就不遵守自杀的约定,他们就活了下来,也就是他们俩站的初始位置要正确。
                现在我们用一个int型数组来存放41个人,数组元素初始值都为0,当第几个数到3的人自杀后,我们用约瑟夫环数标记为几,并记录自杀者的初始位置。当41个人全部自杀后,我们遍历找出倒数前两个自杀的初始位置后,这两个自杀的初始位置就是我们要找的结果。

                现在我们用java代码简单实现:

public static final int MaxNum = 41;  //约瑟夫环最大成员数
public static final int KillNum = 3;  // 数到该数时需要自杀的数字

public static void Josephus(int alive){
     int count = 1;  //统计自杀的人数,每自杀一个人,则count加1,同时也可用来标记约瑟夫成员位置。
     int postion = -1;  // 用来定位约瑟夫环成员位置
     int i = 0;
    //初始化一个数组 数组初始值为0,值为0时为没有自杀。
    int []person = new int[MaxNum];

    //遍历数组,并标记需要自杀的人
    while(count<=MaxNum){
        do{
            postion = (postion+1)%MaxNum;  // 定位约瑟夫环的成员位置
            if(person[postion] == 0){  // 筛选没自杀过的成员,自杀过的成员则不进行处理
                ++i;
            }
            if(i == KillNum){ // 当没自杀过的成员数到3时,该成员自杀。此刻跳出do while 循环,将自杀者标记
                i = 0;
                break;
            }
        }while(true);

        person[postion] = count;    // count用来统计自杀者的个数,同时也标记为初始位置为(postion+1)自杀者的约瑟夫环环号
        System.out.println("位置在"+(postion+1)+"的成员自杀!约瑟夫环号为:"+person[postion]);
        count++;   // 统计自杀的人数,每自杀一个人,则count加1。
    }

    System.out.println("---------------------------------------------------------------------------------------------------------");

    // 计算想要活下来的人需要站的位置
    alive = MaxNum - alive;  //  自杀者的最大约瑟夫环数
    for(i = 0;i<MaxNum;i++){   // 遍历约瑟夫环中的所有人
        if(person[i]>alive){  // 活下来的人的约瑟夫环数大于自杀者的最大约瑟夫环数
            System.out.println("不想要自杀的人应该站的位置是: "+(i+1)+",约瑟夫环号为:"+person[i]);
        }
    }

}

        public static void main(String []args){
            int alive;
            Scanner input = new Scanner(System.in);
            alive = input.nextInt();
            Josephus(alive);
        }

}


测试结果:
2

位置在3的成员自杀!约瑟夫环号为:1
位置在6的成员自杀!约瑟夫环号为:2
位置在9的成员自杀!约瑟夫环号为:3
位置在12的成员自杀!约瑟夫环号为:4
位置在15的成员自杀!约瑟夫环号为:5
位置在18的成员自杀!约瑟夫环号为:6
位置在21的成员自杀!约瑟夫环号为:7
位置在24的成员自杀!约瑟夫环号为:8
位置在27的成员自杀!约瑟夫环号为:9
位置在30的成员自杀!约瑟夫环号为:10
位置在33的成员自杀!约瑟夫环号为:11
位置在36的成员自杀!约瑟夫环号为:12
位置在39的成员自杀!约瑟夫环号为:13
位置在1的成员自杀!约瑟夫环号为:14
位置在5的成员自杀!约瑟夫环号为:15
位置在10的成员自杀!约瑟夫环号为:16
位置在14的成员自杀!约瑟夫环号为:17
位置在19的成员自杀!约瑟夫环号为:18
位置在23的成员自杀!约瑟夫环号为:19
位置在28的成员自杀!约瑟夫环号为:20
位置在32的成员自杀!约瑟夫环号为:21
位置在37的成员自杀!约瑟夫环号为:22
位置在41的成员自杀!约瑟夫环号为:23
位置在7的成员自杀!约瑟夫环号为:24
位置在13的成员自杀!约瑟夫环号为:25
位置在20的成员自杀!约瑟夫环号为:26
位置在26的成员自杀!约瑟夫环号为:27
位置在34的成员自杀!约瑟夫环号为:28
位置在40的成员自杀!约瑟夫环号为:29
位置在8的成员自杀!约瑟夫环号为:30
位置在17的成员自杀!约瑟夫环号为:31
位置在29的成员自杀!约瑟夫环号为:32
位置在38的成员自杀!约瑟夫环号为:33
位置在11的成员自杀!约瑟夫环号为:34
位置在25的成员自杀!约瑟夫环号为:35
位置在2的成员自杀!约瑟夫环号为:36
位置在22的成员自杀!约瑟夫环号为:37
位置在4的成员自杀!约瑟夫环号为:38
位置在35的成员自杀!约瑟夫环号为:39
位置在16的成员自杀!约瑟夫环号为:40
位置在31的成员自杀!约瑟夫环号为:41
————————————————————————————————————————
不想要自杀的人应该站的位置是: 16,约瑟夫环号为:40
不想要自杀的人应该站的位置是: 31,约瑟夫环号为:41

转载于:https://blog.51cto.com/10855700/2065834

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值