约瑟夫下船游戏(python recursion)

30 个人在一条船上,超载,需要 15 人下船。

于是人们排成一队,排队的位置即为他们的编号。

报数,从 1 开始,数到 9 的人下船。

如此循环,直到船上仅剩 15 人为止,问都有哪些编号的人下船了呢?

这是一个链表的循环遍历问题。

虽然递归并不是解决这个问题的最佳实践,但是也能很好的练手。

# -*- coding:UTF-8 -*-

'''
30 个人在一条船上,超载,需要 15 人下船。

于是人们排成一队,排队的位置即为他们的编号。

报数,从 1 开始,数到 9 的人下船。

如此循环,直到船上仅剩 15 人为止,问都有哪些编号的人下船了呢?

calculate people who get down boat

'''

rangeCnt = 9
totle = 15
getDownList = []


def check(people, start, tempCnt):
    print('tempCnt', tempCnt, 'start', start)
    if (tempCnt > 0):
         tempCnt += 1
    for i in range(start, len(people)):
        if (people[i] == 1):
            tempCnt += 1
        if (tempCnt == rangeCnt):
            people[i] = 0
            if (len(people) - len(getDownList) <= totle):
                return
            getDownList.append(i + 1)
            if (i + 1 >= len(people)):
                check(people, 0, 0)
            else:
                check(people, i + 1, 0)
            return
        if (i == len(people) - 1):
            check(people, 0, tempCnt - 1)


people = []
for i in range(0, 30):
    people.append(1)

check(people, 0, 0)

print(getDownList)

执行结果:

tempCnt 0 start 0
tempCnt 0 start 9
tempCnt 0 start 18
tempCnt 0 start 27
tempCnt 2 start 0
tempCnt 0 start 16
tempCnt 0 start 26
tempCnt 2 start 0
tempCnt 0 start 7
tempCnt 0 start 19
tempCnt 0 start 0
tempCnt 0 start 12
tempCnt 0 start 24
tempCnt 2 start 0
tempCnt 0 start 8
tempCnt 0 start 22
tempCnt 3 start 0
tempCnt 0 start 5
tempCnt 0 start 23
tempCnt 2 start 0
[9, 18, 27, 6, 16, 26, 7, 19, 30, 12, 24, 8, 22, 5, 23]

通过代码执行结果我们也能看出执行栈深度!!!果然不是最佳方式。

递归从理解上可能会更加便利,但是往往递归并不是解决问题的最佳手段。

类似斐波那契数(爬楼梯)。

换一种实现方式

# -*- coding:UTF-8 -*-
'''
30 个人在一条船上,超载,需要 15 人下船。

于是人们排成一队,排队的位置即为他们的编号。

报数,从 1 开始,数到 9 的人下船。

如此循环,直到船上仅剩 15 人为止,问都有哪些编号的人下船了呢?

calculate people who get down boat

[9, 18, 27, 6, 16, 26, 7, 19, 30, 12, 24, 8, 22, 5, 23]

'''

rangeCnt = 9
totle = 15
getDownList = []


def check(peopleList):
    downPeopleIndex = 0
    i = 0
    while (i > -1):
        if (peopleList[i] == 1):
            downPeopleIndex += 1
        if (downPeopleIndex == rangeCnt):
            peopleList[i] = 0
            getDownList.append(i+1)
            downPeopleIndex = 0
        if (len(getDownList) == len(peopleList) - totle):
            break
        if (i == len(peopleList) - 1):
            i = 0
            continue
        i += 1


peopleList = []
for i in range(0, 30):
    peopleList.append(1)

check(peopleList)

print(getDownList)

 执行结果

[9, 18, 27, 6, 16, 26, 7, 19, 30, 12, 24, 8, 22, 5, 23]
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值