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

直观理解

老外视频讲解
模拟器演示

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

简单说下: 几个人围成一圈(循环队列), 第一个人开始报数 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. liunx trac 邮件提示功能

    http://trac.edgewall.org/wiki/TracNotification官网上提供的方法.个人觉得不是清楚,不过还是有参考价值的.以下写下自己的添加过程,以作记录. 1.the [ ...

  2. Qt编写的RTSP播放器+视频监控(ffmpeg版本)

    记得四年前就写了个简易版本的,当时写得非常粗糙,代码实在惨不忍睹,时隔多年后,重新写了个版本,同时还解决了以前不支持6画面8画面切换等异形布局的问题.1:可以用过目录下的rtsp.txt设置要显示的视 ...

  3. ubuntu14.04_install_gitlab_platform

    /** author: lihaibo URL:http://www.cnblogs.com/horizonli/p/5321770.html */ 下面是干货 [第一部分 安装] 环境:ubuntu ...

  4. Sublime text3配置LiveReload 浏览器即时刷新

    1.在sublime控件台 install livereload插件(缺点:每次重新打开Sublime都需要启动) 2.配置Preference > Package Settings > ...

  5. ArrayList迭代修改抛出ConcurrentModificationException

    extends:http://www.cnblogs.com/dolphin0520/p/3933551.html Iterator<Integer> iterator = list.it ...

  6. mui+vue+photoclip做APP头像裁剪上传

    做APP由于项目需要,需要做用户头像上传的功能,头像上传包括拍照和相册选择图片进行上传,这里使用的技术是mui封装的plus,在进行图片裁剪的时候,使用的是photoclip来进行裁剪,由于个人在使用 ...

  7. 170821、本地代码上传gitlub

    第一步:建立git仓库 cd到你的本地项目根目录下,执行git命令 git init #初始化项目 第二步:将项目的所有文件添加到仓库中 git add . 或者git add -A #如果想添加某个 ...

  8. Mybatis批量insert报错的解决办法【the right syntax to use near '' at line...】

    Java中使用Mybatis批量插入数据时Mapper.xml中的sql如下: <insert id="batchSave"> into t_emp(emp_name, ...

  9. ELK之生产日志收集构架(filebeat-logstash-redis-logstash-elasticsearch-kibana)

    本次构架图如下 说明: 1,前端服务器只启动轻量级日志收集工具filebeat(不需要JDK环境) 2,收集的日志不进过处理直接发送到redis消息队列 3,redis消息队列只是暂时存储日志数据,不 ...

  10. TOP100summit 2017:亚马逊Echo音箱能够语音识人,华人工程师揭秘设计原理

      本文编辑:Cynthia 2017年,人工智能的消费产品落地聚焦在了智能音箱上,谷歌.亚马逊纷纷推出智能音箱产品,国内的阿里巴巴推出天猫精灵,小米推出小米AI音箱.智能音箱通过语音可以发出指令,未 ...