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

来源:互联网 发布:牛耳软件教育 编辑:程序博客网 时间:2024/04/30 05:23

一道类似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 cntcalc_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 cntcalc_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 mlog = m.logdef calc_out_1(num):    return pow(2, int(log(num)/log(2)))calc_out_1(156)
0 0
原创粉丝点击