问题描述

N个人围成一个圈, 从第一个人开始报数, 报到M的人出圈, 剩下的人继续从1开始报数, 报到M的人出圈;如此往复, 直到所有人出圈.

列表解决

  1. def solution_list(n, m):
  2. """
  3. 初始化一个长度为n的列表, 默认值为True. 当某个元素出圈时, 将其置为False.
  4. 循环迭代这个列表, 遇到值为False的元素则跳过, 当列表中全为False时表示所有人
  5. 都已出圈.
  6. """
  7. # 初始化列表
  8. people = []
  9. for _ in range(n):
  10. people.append(True)
  11. result = []
  12. num = 1
  13. while any(people):
  14. for index, p in enumerate(people):
  15. if p:
  16. if num == m: # 出圈操作
  17. people[index] = False
  18. result.append(index + 1)
  19. num = 1
  20. else:
  21. num += 1
  22. print('-' * 25)
  23. print(f'\n总人数为{n}, 报数为{m}')
  24. print(f'约瑟夫序列为:\n {result}\n')
  25. print('-' * 25)
  1. def solution_list2(n, m):
  2. """
  3. 这是上面这种思路的另一种解法, 将圈内和圈外表示成0和1.
  4. 这里实现循环迭代的方式我第一次遇到, 记录一下
  5. """
  6. people = [0 for _ in range(n)]
  7. alive = n # 剩余人数
  8. index = 0
  9. num = 0 # 计数器, 当index == m时出圈
  10. result = []
  11. while alive > 0:
  12. num += 1 - people[index] # 每轮到一个人报数, 不论0或1都进行计数
  13. if num == m:
  14. result.append(index + 1) # 出圈
  15. people[index] = 1 # 将出圈人置为 1
  16. alive -= 1 # 剩余人数 - 1
  17. num = 0 # 重置计数器
  18. # 与总人数 n 取余, 可以实现index在 0 ~ count -1之间一直循环, 达到循环迭代的目的
  19. index = (index + 1) % n
  20. print('-' * 25)
  21. print(f'\n总人数为{n}, 报数为{m}')
  22. print(f'约瑟夫序列为:\n {result}\n')
  23. print('-' * 25)

循环链表解决

  1. class Node:
  2. """节点"""
  3. def __init__(self, value):
  4. self.data = value
  5. self.next = None
  6. def __repr__(self):
  7. return f'Node: {self.data}'
  8. class CircularLinkedList:
  9. """循环链表"""
  10. def __init__(self):
  11. self.rear = None # 尾节点
  12. def is_empty(self):
  13. return self.rear is None
  14. def append(self, elem):
  15. """尾插法"""
  16. temp = Node(elem)
  17. if self.rear is None:
  18. temp.next = temp
  19. self.rear = temp
  20. else:
  21. temp.next = self.rear.next
  22. self.rear.next = temp
  23. self.rear = temp
  24. def solution_circular_linked_list(n, m):
  25. """
  26. 通过循环链表解决, 每次出圈弹出该节点
  27. """
  28. clist = CircularLinkedList()
  29. for i in range(n):
  30. clist.append(i + 1)
  31. result = []
  32. pre = clist.rear # 当前节点的上一个节点
  33. cur = clist.rear.next # 当前节点
  34. num = 0 # 计数器
  35. while cur.next is not cur:
  36. num += 1
  37. if num == m: # 出圈
  38. result.append(cur.data)
  39. pre.next = cur.next # 弹出当前节点
  40. num = 0 # 重置计数器
  41. else:
  42. pre = pre.next
  43. cur = cur.next
  44. result.append(cur.data)
  45. print('-' * 25)
  46. print(f'\n总人数为{n}, 报数为{m}')
  47. print(f'约瑟夫序列为:\n {result}\n')
  48. print('-' * 25)

参考:

经典算法--约瑟夫环问题的三种解法

百度百科

约瑟夫问题 -- python实现的更多相关文章

  1. 简洁之美 -约瑟夫环的python 解法

    问题描述: 约瑟夫环问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到k的那个人出列:他的下一个人又从1开始报数,数到k的那个人又出列:依此规律重复下 ...

  2. 约瑟夫环问题及python与c++实现效率对比

    约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重 ...

  3. python中使用queue实现约瑟夫环(约瑟夫问题)求解

    约瑟夫问题:是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围. 从编号为k的人开始报数,数到m的那个人出列:他的下一个人又从1开始报数,数到m的那个人又出列: 依 ...

  4. 10行Python代码解决约瑟夫环(模拟)

    http://blog.csdn.net/dengyaolongacmblog/article/details/39208675 #!/usr/bin/env python # coding: utf ...

  5. 丢手绢问题(约瑟夫问题)的python实现

    约瑟夫问题是个有名的问题:N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉. def fnA(p, personNum, cnt): times = cnt // pe ...

  6. python - 约瑟夫问题

    在罗马人占领乔塔帕特后,39 个犹太人与约瑟夫及他的朋友躲到一个洞中.39个犹太人决定宁愿死也不要被敌人俘虏,商定一种特殊的方式自杀,41个人排成一个圆圈,由第1个人开始报数,每报到第3人该人就必须自 ...

  7. Python练习——约瑟夫环问题、用类方法描述一个数字时钟

    一.约瑟夫环问题 有15个基督徒和15个非基督徒在海上遇险,为了能让一部分人活下来不得不将其中15个人扔到海里面去,有个人想了个办法就是大家围成一个圈,由某个人开始从1报数,报到9的人就扔到海里面,他 ...

  8. python算法:约瑟夫问题

    据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特後,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被人抓到,于是决定了一个自杀方式,41 ...

  9. 浅谈如何使用python抓取网页中的动态数据

    我们经常会发现网页中的许多数据并不是写死在HTML中的,而是通过js动态载入的.所以也就引出了什么是动态数据的概念, 动态数据在这里指的是网页中由Javascript动态生成的页面内容,是在页面加载到 ...

随机推荐

  1. djanao请求生命周期

    djanao请求生命周期 浏览器发送请求到服务端 服务端的wsgi服务器接收到来自浏览器的请求, 对request做一些预处理, 把浏览器的请求信息(请求方式, 请求头, socket信息等)都封装在 ...

  2. linux任务计划cron、chkconfig工具、systemd管理服务、unit和target介绍

    第8周第1次课(5月14日) 课程内容: 10.23 linux任务计划cron10.24 chkconfig工具10.25 systemd管理服务10.26 unit介绍10.27 target介绍 ...

  3. RestSharp Simple REST and HTTP API Client for .NET

    var client = new RestClient("http://example.com"); // client.Authenticator = new HttpBasic ...

  4. Mac从拆箱到入门

    Mac从拆箱到入门   记录首次使用Mac的我的历程,不是专业的Mac使用教程,只是简单的记录.还有我在使用过程中一些用到的功能都一些小提示吧.  1.首次开机配置,对于一个完全的新手来说(也就是我) ...

  5. HBase(2) Java 操作 HBase 教程

    目录 一.简介 二.hbase-client 引入 三.连接操作 四.表操作 五.运行测试 FAQ 参考文档 一.简介 在上一篇文章 HBase 基础入门 中,我们已经介绍了 HBase 的一些基本概 ...

  6. 01Shell入门02-echo和printf

    输出方式 小知识 echo echo -e 可以控制字体颜色和背景颜色输出 示例 echo -e "\033[41;36m Hello world \033[0m" [root@h ...

  7. SMProxy,让你的数据库操作快三倍!

    SMProxy GITHUB:https://github.com/louislivi/smproxy 喜欢请star 中文 | English /$$$$$$ /$$ /$$ /$$$$$$$ /$ ...

  8. 【开发记录】Linux常用命令记录(一)

    记录CentOS下,常用的命令.有时候很难记得清楚,同时方便新来的同学查阅.(将不停的追加和完善) 1)查看CPU情况 cat /proc/cpuinfo |grep "model name ...

  9. Python报错ERROR: Command errored out with exit status 1:

    解决方法: 1.以管理员身份打开cmd 2.pip install robotframework-AutoItLibrary (本次安装时Python基于3.7.3,pip为最新版本) 3.安装成功

  10. vmware虚拟机扩大硬盘

    记录一下对vmware虚拟机扩大硬盘的过程.操作有风险,重要数据请先进行备份. 1.首先在vcenter中将虚拟机下电,然后编辑虚拟机,将虚拟机硬盘扩大.具体操作见下图 2.打开虚拟机电源,利用fdi ...