python解决约瑟夫环问题(容易理解版)

python解决约瑟夫环问题(容易理解版)

约瑟夫环问题:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到k的那个人被杀掉;他的下一个人又从1开始报数,数到k的那个人又被杀掉;依此规律重复下去,直到圆桌周围的人只剩最后一个。

第一次写博客,请大家多多指教。

超级容易理解版:
思路:刚开始把所有的人放到一个列表里面去,报的数字不是3就把这个人放到列表的最后一个位置上面去,如果是3就把这个数字从列表中去掉。直到列表剩下一个人为止,代码如下:

def josephus(n,k):
    #n代表总人数,k代表报数的数字
    List = list(range(1,n+1))
    index = 0
    while List:
        temp = List.pop(0)
        index += 1
        if index == k:
            index = 0
            continue
        List.append(temp)
        if len(List)==1:
            print(List)
            break

if __name__ == '__main__':
    josephus(41,3)

---------------------------------------------------我是分割线------------------------------------------------------------------

单向循环链表法(为了巩固链表的知识而去使用的方法)
思路:就是运用单向链表的循环,其实跟上面一种方法差不多,代码如下:

class Node(object):
    """结点"""
    def __init__(self,item):
        self.elem = item
        self.next = None

class SingleCycleLinkList(object):
    """单向循环链表"""
    def __init__(self):
        self.head = None

    def append(self,item):
        node = Node(item)
        if self.head is None:
            self.head = node
            node.next = node
        else:
            cur = self.head
            while cur.next != self.head:
                cur = cur.next
            cur.next = node
            node.next = self.head

    def travel(self):
        cur = self.head
        while cur.next != self.head:
            print(cur.elem, end=" ")
            cur = cur.next
        print(cur.elem)

    def remove(self,item):
        '''删除节点'''
        cur = self.head
        pre = None
        while cur.next != self.head:
            if cur.elem == item:
                #头节点的情况
                if cur == self.head:
                    rear = self.head
                    while rear.next != self.head:
                        rear = rear.next
                    rear.next = cur.next
                    self.head = cur.next
                else:
                    #中间结点的情况
                    pre.next = cur.next
                return
            else:
                pre = cur
                cur = cur.next
    #尾节点的情况和一个元素的情况
        if cur.elem == item:
                # 一个元素的情况
            if cur == self.head:
                self.head = None
                # 尾节点元素的情况
            else:
                pre.next = self.head
                # pre.next = cur.next

    def judgement(self):
        cur = self.head
        count = 1
        while cur != cur.next :
            cur = cur.next
            count += 1
            if count == 3:
                self.remove(cur.elem)
                print("%d-->"%cur.elem,end="")
                count = 0
        print(cur.elem)

if __name__ == '__main__':
    sll = SingleCycleLinkList()
    for i in range(1,42):
        sll.append(i)
    sll.judgement()

  • 62
    点赞
  • 173
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
约瑟夫环问题约瑟夫环问题是一个经典的问题,描述如下:n个人围成一圈,从第一个人开始报数,数到m的人出圈,然后从出圈的下一个人开始重新报数,数到m的人再次出圈,如此重复,直到所有人出圈为止。现在我们需要编写一个程序来求出出圈的顺序。 解决这个问题的一个有效的方法是使用循环队列。我们可以将n个人依次加入到队列中,然后每次从队列中取出m-1个人并重新加入到队列末尾,直到队列中只剩下一个人为止,这个人就是最后一个出圈的人。 下面是使用Python队列来解决约瑟夫环问题的代码: ```python from queue import Queue def josephus(n, m): # 创建一个队列,并将n个人依次加入到队列中 q = Queue() for i in range(1, n+1): q.put(i) # 开始报数,直到队列中只剩下一个人 while q.qsize() > 1: # 将队列头部的m-1个人依次取出,并重新加入到队列末尾 for i in range(m-1): q.put(q.get()) # 将队列头部的第m个人取出并输出 print(q.get(), end=', ') # 输出最后一个出圈的人 print(q.get()) # 测试 josephus(7, 3) # 输出:3, 6, 2, 7, 5, 1, 4 ``` 分组问题: 分组问题是另一个常见的问题,描述如下:有n个人,需要将他们分成m组,且每组人数尽量相等。现在我们需要编写一个程序来求出分组方案。 解决这个问题的一个有效的方法是使用队列。我们可以将n个人依次加入到队列中,然后依次从队列中取出m个人,将他们分为一组,并输出分组方案,直到队列中的人都被分完为止。 下面是使用Python队列来解决分组问题的代码: ```python from queue import Queue def group(n, m): # 创建一个队列,并将n个人依次加入到队列中 q = Queue() for i in range(1, n+1): q.put(i) # 依次从队列中取出m个人,将他们分为一组,并输出分组方案 while not q.empty(): group = [] for i in range(m): if not q.empty(): group.append(q.get()) print(group) # 测试 group(10, 3) # 输出:[1, 2, 3], [4, 5, 6], [7, 8, 9], [10] ``` 以上就是使用Python队列解决约瑟夫环问题和分组问题的方法。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

自由小冰儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值