华为机考-删数问题

题目:有一个数组a[N]顺序存放0~N-1,要求每隔两个数删掉一个数,到末尾时循环至开头继续进行,求最后一个被删掉的数的原始下标位置。以8个数(N=7)为例:{0,1,2,3,4,5,6,7},0->1->2(删除)->3->4->5(删除)->6->7->0(删除),如此循环直到最后一个数被删除。

输入:

每组数据为一行一个整数n(小于等于1000),为数组成员数,如果大于1000,则对a[999]进行计算。

输出:

一行输出最后一个被删掉的数的原始下标位置。

这道题是一个约瑟夫环问题,有特定的公式推导,公式的最后结果是:

f(n,m)=(f(n-1,m)+m)%n

可以看下面这张表:

在这里插入图片描述

 当n=10,先死掉的是索引为2的数,接下来数组长度变为9,死掉的是索引为2的数,依次直到n=1,存活的是索引为0的数d,那么我们再看看d每次存在的位置

在这里插入图片描述

   有f(10)=3,f(9)=0,f(8)=6...f(2)=1,f(1)=0 ,对比f(10)和f(9),可以得到(f(9)+3)%10 = f(10),可以推导出f(n,m)=(f(n-1,m)+m)%n

const readline = require('readline');
     
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
})
    
var arr = []
rl.on('line', (line) => {
    var num = Number(line.trim())
    getResult(num)
})
//递推公式:f(n,m)=(f(n-1,m)+m) % n
//n是数组长度,m是间隔数
function getResult(num){
    var last = 0        //初始值,只有一个数,那么这个数的下标值为0
    var m = 3
    for(var i = 2;i <= num;i++){        //i从1开始,一直推到num
        last = (last+m)%i        //递推公式,从小往大推,last表示当数组长度为i时,剩下数的下标值
    }
    console.log(last)        //推到最后就是数组长度为num,可以存活数的下标值
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值