约瑟夫问题(历史战争问题)

直观理解

老外视频讲解
模拟器演示

约瑟夫问题 数学姥公众号 讲的最清楚 背景及,推倒过程讲解得很清晰,旨在提高人们对数据的兴趣

简单说下: 几个人围成一圈(循环队列), 第一个人开始报数 1 2 1 2, 依次进行,喊2的被杀掉. 如果人数是n,则最后剩下几号?

约瑟夫斯问题是个蛮好玩的问题。这个问题来源于一个犹太叛徒,约瑟夫斯是犹太人,参与了对罗马的起义,并被任命为起义部队的军事长官。不过在后来罗马军团的进攻下,犹太人的起义很快失败了,约瑟夫斯带领这39名犹太士兵躲到了一个山洞中,山洞则被罗马人包围。士兵们坚贞不屈,宁可死也不肯投降,然而约瑟夫斯不想死,又不敢说出来。于是约瑟夫斯利用了犹太教中关于自杀耻辱的教义,说咱们不能自杀,咱们可以互相杀,怎么互相杀,谁来杀呢?这样

40人围成一圈,然后连续1,2,1,2……报数,所有报2的被同伴杀死,直到最后一个,最后一个自杀者承担教义中自杀的耻辱。约瑟夫斯是个数学家,他当然很快就知道自己应该站在哪个位置而不会被杀死。当所有人都被杀死后,他走出山洞,投降了罗马人。

那么,现在的问题是,就按照1212报数,报2被杀死的规则,当人数n不止40时,站在哪个位置能最后活下来?

最终推倒出的解决公式:

如果n个人,则最终f(n)号活下来.

栗子1: f(100)=f(64+36)=2*36+1=73,100

这里为何64+36呢? 2^6=64, 2^7=128>100, 所以只能36了.
依据公式,可以推倒出 n = 100, f(100)=73

栗子2: n = 6,最终存活下第5个Susan
["Bill", "David", "Kent", "Jane", "Susan", "Brad"]

搞清楚了这个问题是啥,和解题思路.后用程序来实现它.

  • 不得不说,数据这玩意如果不用符号来标识, 那么语句废话再多也描述不到位问题.
  • 核心乐趣是推倒这个问题通用算法的结论. 其他的都是锦上添花的作用. 有种朝闻道,夕死可矣的感觉

用Python实现的数据结构与算法:队列

队列: 对尾加,对首出

remainder 余数

bin 二进制
dec 十进制
rem 余数

Queue 队列
enqueue 排队 对尾
dequeue 出对 对首

front 在前面
rear  在后面

值得注意的是,Queue类只实现了简单队列,上述问题实际上需要用循环队列来解决。在报数过程中,通过“将(从队首)出队的人再入队(到队尾)”来模拟循环队列的行为。具体代码如下:

#!/usr/bin/env python
# coding=utf-8

# 实现每次 对尾添加  对首出现

class Queue:
    def __init__(self):
        self.arr = []

    def push(self, i):
        self.arr.append(i)

    def pop(self):
        return self.arr.pop(0)

    def size(self):
        return len(self.arr)

# arr1 = Queue()
# arr1.push(1)
# arr1.push(2)
# arr1.push(3)
# arr1.pop()
# print(arr1.arr)

## 解决约瑟夫问题
#### 模拟循环队列  对首出队 对尾追加  弹出对首 返回弹出对首

def josephus(arr1, num):
    ## 入队
    q = Queue()
    for name in arr1:
        q.push(name)

    # 对首出列, 添加到对尾
    while q.size() > 1:
        for i in range(num):
            q.push(q.pop())
        q.pop()
    return q.pop()

print(josephus(["Bill", "David", "Kent", "Jane", "Susan", "Brad"], 3))

[py]约瑟夫问题-循环队列的更多相关文章

  1. 约瑟夫环-循环队列算法(曾微软,google笔试题)

    这也是我们聚会时常常做的游戏之一. 算法思路: 此处我使用循环链表模拟人围城一圈,每一个结点代表一个人.链表是一个有序链表,链表结点数据域是一个整型,代表人的序号.出局等同于链表删除元素,每次出局后重 ...

  2. 使用 JavaScript 实现基本队列、优先队列和循环队列

    1.基本队列的实现 基本队列的方法中,包含了 ①向队列(尾部)中添加元素(enqueue).②(从队列头部)删除元素(dequeue).③查看队列头部的元素(front).④查看队列是否为空(isEm ...

  3. Javascript数据结构与算法--队列(顺序队列、优先队列、循环队列)的实现与用法

    前言 队列和栈非常类似,前面已经讲过了栈的实现与用法,现在我们来说说队列. 队列介绍 队列遵循FIFO(First In First Out,先进先出)原则的一组有序的项. 队列是一种特殊的线性表,特 ...

  4. python 循环队列的实现

    最近在做一个东西的时候发现需要用到循环队列,实现先进先出(FIFO),不断往里面添加数据,当达到某个限定值时,最先进去的出去,然后再添加.之后需要对队列里面的内容进行一个筛选,作其他处理.首先我想到了 ...

  5. C++数组实现的循环队列

    #include<iostream> #include <string> /* 功能:数组实现的循环队列,C++实现,学习参考 */ using namespace std; ...

  6. C ~ 链式队列与循环队列

          此处的链式与循环队列可以应用于BFS和树的层序遍历.下面是对其结构和基本操作的程序描述. 1.循环队列 解决循环队列的队空和队满的方法: [1].增加一个参数count,用来记录数组中当前 ...

  7. 数据结构算法C语言实现(十二)--- 3.4循环队列&队列的顺序表示和实现

    一.简述 空队列的处理方法:1.另设一个标志位以区别队列是空还是满:2.少用一个元素空间,约定以队列头指针在队尾指针下一位置上作为队列呈满的状态的标志. 二.头文件 //3_4_part1.h /** ...

  8. Atitit.提升软件稳定性---基于数据库实现的持久化 循环队列 环形队列

    Atitit.提升软件稳定性---基于数据库实现的持久化  循环队列 环形队列 1. 前言::选型(马) 1 2. 实现java.util.queue接口 1 3. 当前指针的2个实现方式 1 1.1 ...

  9. 循环队列+堆优化dijkstra最短路 BZOJ 4152: [AMPPZ2014]The Captain

    循环队列基础知识 1.循环队列需要几个参数来确定 循环队列需要2个参数,front和rear 2.循环队列各个参数的含义 (1)队列初始化时,front和rear值都为零: (2)当队列不为空时,fr ...

随机推荐

  1. JS-过滤敏感词【RegExp】

    来自腾讯课堂笔记:https://ke.qq.com/webcourse/index.html#course_id=152997&term_id=100174752&taid=8010 ...

  2. 【llinux】yum命令出现Loaded plugins: fastestmirror Determining fastest mirrors

    在进行yum 安装的时候.报错了. Loaded plugins: fastestmirror Determining fastest mirrors fastestmirror是yum的一个加速插件 ...

  3. java高级---->Thread之ExecutorService的使用

    今天我们通过实例来学习一下ExecutorService的用法.我徒然学会了抗拒热闹,却还来不及透悟真正的冷清. ExecutorService的简单实例 一.ExecutorService的简单使用 ...

  4. Word 2010 制作文档结构之图标自动编号设置

    注意: 使用图片自动编号时,如果文档标题使用的样式是通过“将所选内容保存为新快速样式”所生成的样式,则图片自动编号不会生效 因此设置标题样式时,不要 新建样式,直接使用word预设的“标题 1”样式和 ...

  5. Linux命令 uname:查看系统与内核相关信息

    zh@zh:~$uname --help zh@zh:~$uname -a //所有系统相关的信息

  6. php sqlserver及xdebug扩展配置

    ;extension=php_bz2.dllextension=php_curl.dll;extension=php_fileinfo.dll;extension=php_ftp.dll;extens ...

  7. laravel blade模板里调用路由方法重定向

    @if (Session::get('user') == NULL) {!!Redirect::to('login')!!} @endif or @if (Session::get('user') = ...

  8. sysbench 压力测试工具

    一.sysbench压力测试工具简介: sysbench是一个开源的.模块化的.跨平台的多线程性能测试工具,可以用来进行CPU.内存.磁盘I/O.线程.数据库的性能测试.目前支持的数据库有MySQL. ...

  9. 圆形CD绘制 (扇形)

    参考: Egret教程Arc是使用示例:http://edn.egret.com/cn/article/index/id/673 我封装的工具类: /** * 圆形进度 * @author chenk ...

  10. EUI ViewStack实现选项卡组件 (封装了一个UI类)

    封装一个选项卡的UI,用来应付游戏中各种需要选项卡的界面. 例如背包,背包界面的选项卡可以切换装备.物品.符文.宝箱. 下图方法的实现参考:EUI ViewStack实现选项卡组件 假如在主页Home ...