约瑟夫环2

问题描述:

有n个人站成一列。并从头到尾给他们编号,第一个人编号为1。然后从头开始报数,第一轮依次报1,2,1,2...然后报到2的人出局。接着第二轮再从上一轮最后一个报数的人开始依次报1,2,3,1,2,3...报到2,3的人出局。以此类推直到剩下以后一个人。现在需要求的即是这个人的编号

1 2 1 2 …1 2 31 2 3 ….1 2 3 4 1 2 3 4….1 2 3 4 5 1 2 3 4 5 …..知道最后只剩下一个元素】


 举个例子:假设n = 24,第一个人编号为1。
(1)第一轮:依次报1,2,1,2...然后报到2的人出局,则第一轮过后未出局的编号为1、3、5、7、9、11、13、15、17、19、21、23;
(2)第二轮:从上一轮最后一个报数的人开始依次报1,2,3,1,2,3...报到2,3的人出局。我这里做的处理是,先将上一轮最后一个报数的编号移动到最前面,即23、1、3、5、7、9、11、13、15、17、19、21;然后开始第二轮报数,未出局的编号为23、5、11、17;
(3)第三轮:从上一轮最后一个报数的人开始依次报1,2,3,4,1,2,3,4...报到2,3,4的人出局。同样,我这里做的处理是,先将上一轮最后一个报数的编号移动到最前面,即17、23、5、11;然后开始第三轮报数,未出局的编号为17,此时链表中仅剩一个节点,故程序结束。

解题思路:

将编号 1 - n放入到列表中,当列表中的元素个数大于1的时候进行循环:第二轮循环:【每一轮循环表示一次报数过程】设置变量round并计算当前编号的所报的数字【(cur+1)%roud】,进行判断:如果所报的数字是1,则继续下一个数字;如果所报的数字不是1,则执行列表的删除操作。执行完一轮报数的过程后,需要将左后一个数字移动到列表的第一个位置(题意:从上次报数的最后一个开始报编号1)【利用列表中的 pop()方法:默认删除最后一个元素,并返回最后一个元素的值 】,最后跳出循环并返回列表中唯一一个元素

# -*- coding:utf-8 -*-
class Joseph:
    def getResult(self, n):
        # write code here
        if n < 0:
            return -1
        list1 = []
        i , cur = 0,0
        roud = 2
        for i in range(1,n+1):# 将编号加入到列表中
            list1.append(i)
        while len(list1) > 1:
            i = 0
            while len(list1) > 1 and i < len(list1):
                cur = (cur + 1)%roud # 计算出当前所报的数字
                if cur == 1:# 判断如果数字为1,不进行处理
                    i += 1
                else: # 如果数字不是1,进行删除操作
                    list1.remove(list1[i])
            roud += 1
            cur = 0
            if len(list1) > 1:
                list1.insert(0,list1.pop())# 将最后一个元素删除并插入到首位
        return list1.pop()

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
约瑟夫环是一个古老的数学问题,该问题最早由约瑟夫·弗拉维奥于1世纪通过犹太历史记载引入数学。问题的背景是:在古代,有一个40个人组成的团体,他们在围成一个圆圈坐下,从某个人开始报数,报到某个数的人将被淘汰。然后,从下一个人开始重新报数,再次报到某个数的人又被淘汰。如此循环,直到只剩下一个人为止。 这个问题可以用数学的方式进行求解。我们可以使用递归的方法来解决。假设初始位置为0,报到第m个人就出列,现在求剩下的最后一个人的位置。 首先,我们可以观察到,每次淘汰的人在他前任的基础上向前移动了m位,同时,由于圆圈的连续性,还需要将当前位置对总人数取余。因此,第一轮结束后,第一个出列的人的位置为m-1。接下来,我们可以继续观察,第二轮开始时,剩下的人的位置相当于前一轮剩下人的位置再向前移动m位取余,即为(m-1+m) mod n,其中n为前一轮剩下的人数,也就是总人数。 按照上述的计算逻辑和递归的方法,我们可以得到第k轮淘汰之后剩下的人的位置为: f(1) = 0 f(k) = (f(k-1) + m) mod n 通过以上的递归关系,我们可以迭代求解,直到最后一轮淘汰,剩下的人的位置即为答案。 总结起来,约瑟夫环是一个经典的数学问题,通过构建递归关系并利用数学计算,我们可以求解出最后一个留下来的人在圆圈中的位置。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值