谁是老大--一道类似Joseph环的智力题

一道类似Joseph环的智力题

这是一个在面试中被问到的问题,其实细想起来很简单。但当时只给了两分钟,没能直接给出解决方案。

问题描述

有156个海盗在一个岛上,他们决定选一个人出来做老大,由于人这么多,选谁当老大一直没有选好,于是他们想出来一个办法,把这156个人从1到156编号,然后按1, 2, 1, 2, …报数,报到1的退出选举,剩下来的人继续重新报数,然后把‘1’的人踢出局,最后剩下来的就是老大。那么请问,谁是老大?

解题思路

这个问题有点像经典的Joseph环,但其实要比Joseph环容易。由于每次是报‘1’的人出局,所以我们可以用x % 2 == 0来作为判断条件。于是程序可以写成下面这样:
(python)

def calc_out_2(num):
    nlist = range(1, num)
    cnt = 1
    while len(nlist) != 1:
        nlist = [x / 2 for x in nlist if x % 2 == 0]
        cnt *= 2
    return cnt

calc_out_2(156)

装B一下,用一下函数式编程,可以写成这样:

def calc_out_3(num):
    nlist = range(1, num)
    cnt = 1
    while len(nlist) != 1:
        nlist = map(lambda x:x/2, filter(lambda x:x%2 == 0, nlist))
        cnt *= 2
    return cnt
calc_out_1(156)

再仔细的分析一下,由于每次都是‘1’出局,所以定义F(n)为n个海盗选老大的函数。

F(2) = 2
F(3) = 2
F(4) = 4
F(5) = 4
F(6) = 4
F(7) = 4
F(8) = 8
F(9) = 8

看出来规律了吧:

F(n) = max(2^x) if 2^x < n

重写Python代码如下:

import math as m
log = m.log

def calc_out_1(num):
    return pow(2, int(log(num)/log(2)))

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值