每日一道算法题

day04

题目:如何利用约瑟夫环来保护你和你的朋友?

题目描述:

        传说著名犹太学家Josephus有过以下的故事:在罗马人占领桥塔帕特后,39个犹太人与Josephus及他的朋友躲到一个洞里,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人拍成了一个圆圈,从第一个人开始数数,每数到第3个人该人就必须自杀,然后再由下一个人开始重新报数,直到所有人都自杀身亡为止。

        虽然Josephus和他的朋友并不愿遵从,但是Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个和第31个位置,于是逃过了这场死亡游戏。

        约瑟夫问题可用代数分析来求解,假设现在你与m个朋友不行参与了这个游戏,你要如何保护你和你的朋友?

 解析:

        实际上只要画两个圆圈就可以让自己与朋友免于死亡游戏,这两个圆圈中内圈是排列顺序,而外圈是自杀顺序,如图所示:

 如果要使用公式来求解,那么只要将阵列当作环状来处理,在阵列中由计数1开始,每三个数得到一个计数,直到计数为41为止,然后将阵列由索引1开始列出,就可以得知每个位置的自杀顺序,这就是约瑟夫排列,41人报数的约瑟夫排列如下所示:

14 36 1 38 15 2 24 30 3 16 34 4 25 17 5 40 31 6 18 26 7 37 19  8 35 27 9 20 32 10  41 21 11 28 39 12 22  33  13  29 23

 由上可知,最后一个自杀人是在第31个位置,而倒数第二个自杀的人要排在第16个位置,之前的人都死了,所以他们也就不知道约瑟夫与他的朋友有没有遵守游戏规则,是在代码为:

<script>

var N=41,M=3,man=[],count=1,i=0,pos=-1,

  alive=3;//想救的人数

  while(count<=N){

    do{

      pos=(pos+1)%N;//环状处理

      if(!man[pos])

        i++;

        if(i==M){//报数为3

          i=0;

          break;

        }

    }while(1);

    man[pos]=count;

    count++;

  }

  console.log('约瑟夫排列:',man.join(''));

  var txt='L表示要救的'+alive+'个人要放的位置:';

  for(i=0;i<N;i++){

    if(man[i]>(N-alive))

    txt+='L';

    else

      txt+='D';

      if((i+1)%5==0)

      txt+=' ';

  }

  console.log(txt);

</script>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值