循环杀人游戏
作者:互联网
事情是这样的:
在浏览一个关于二分法的帖子的时候,有热心评论者出了一个题目,抱着试试看的态度尝试了一下。
原题如下:
1.初始有N个人编好号1至N。
2.站成一圈
3.从1号开始隔一个杀一个
求:最后活着的是多少号?
emmmmm.......[黑人问号],找不到图了....
二分法还没理解深刻呢,想这个干啥,可是这个有趣啊,试试吧,那就试试吧.....脑子飞快的转动,该怎么抽象这个问题呢,唉,有了
假设有一百个人,每人拿到一个号码,从一到一百,每人对应一个数字,看做是一个数组。经过第一轮杀戮,保留下来的人就是原来数组删掉一些元素的结果,
以此类推,最后只留下一个元素,也就是那个幸运儿啦!
问题来了,哪些元素是该删除的呢?
第一轮把幸存者放到一个集合,1,3,5..... 唉!奇数项被保留了,奇数,奇数,对了,对2取余(i%2)
第二轮这样,第三轮也这样?总觉得哪里不对劲!
先写一段试试:
function f(n) { let arr = [] for (let i=0;i<n;i++) { arr.push(i+1) } while (arr.length>1) { let _r = [] for (let i=0;i<arr.length;i++) { i%2===0?_r.push(arr[i]):'' } arr = _r } return arr }
测试了几个n,发现每次留下来的都是1号,不对,问题在哪呢,哦,他们是站成一圈的,不可能每次都从集合删除偶数项
[抓头发],原来我头发越来越少是因为这个,赶紧放下不安分的手!
想想....唉,发现这个跟我每次删除的最后一个元素是不是数组的最后一个元素有关,如果我上一轮最后删的是最后一个数,那新一轮会跳过第一个从第二个开始删,也就是偶数项;
那如果不是最后一个元素呢,那就应该从第一个开始删了,对奇数项,em.......好像是这么回事!
function f(n) { let arr = [] for (let i=0;i<n;i++) { arr.push(i+1) } let _k = 0 // 判断需要杀的是哪个倒霉蛋 while (arr.length>1) { let _r = [] let _i = 0 for (let i=0;i<arr.length;i++) { i%2===_k?_r.push(arr[i]):_i=i } if (_i===arr.length-1) {_k=0} else {_k=1} arr = _r } return arr }
em.......好像就是这么回事了
那我不想从一号开始了,我想从某号开始该怎么办呢?
这还不简单,再加个参数进去呗,说干就干!
function f(n,m) { // n:人数 m:从几号开始 let arr = [] for (let i=0;i<n;i++) { arr.push(i+1) } arr = [...arr.slice(m-1),...arr.slice(0,m-1)] let _k = 0 let _r = arr while (arr.length>1) { let _r = [] let _i = 0 for (let i=0;i<arr.length;i++) { i%2===_k?_r.push(arr[i]):_i=i } if (_i===arr.length-1) {_k=0} else {_k=1} arr = _r } return arr }
em.....
隔两个人一杀,最后留下来的会是两个人吗【抓头发】?
标签:.....,游戏,奇数,一个,元素,最后,循环,let,杀人 来源: https://www.cnblogs.com/xiawg/p/12124445.html