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

直观理解

老外视频讲解
模拟器演示

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

简单说下: 几个人围成一圈(循环队列), 第一个人开始报数 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. U盘安装centos6.4:缺少iso 9660映像

    方法: 1.下载安装的ISO文件    到www.centos.org网站下载对应的Centos 6.4安装文件.下载站点我一般选择网易镜像站点    64位下载参考链接:http://mirrors ...

  2. Trie树的分析与实现

    字典树 又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种.典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计.它的优点是:利用字符串的 ...

  3. linux中的标准输出和输入

    ===============1.有些人经常问我这个问题问题=========== 经常在脚本里面看到这个    2>&1     表示什么意思啊? ==============2.理论 ...

  4. mysql架构图

    整体架构图 访问控制图

  5. php底层变量分析

    <?php //数组引用 $arr = array('a','b','c','d'); $x = & $arr[1]; $tmp = $arr; $arr[1] = 'e'; echo ...

  6. [Sdoi2016]平凡的骰子

    描述 这是一枚平凡的骰子.它是一个均质凸多面体,表面有n个端点,有f个面,每一面是一个凸多边形,且任意两面不共面.将这枚骰子抛向空中,骰子落地的时候不会发生二次弹跳(这是一种非常理想的情况).你希望知 ...

  7. 如何在Computer下添加System Folder(续)

    之前的一篇博客如何在Computer下添加System Folder里提到需要每次都使用一个新的guid,否则再次在"HKEY_LOCAL_MACHINE\SOFTWARE\Microsof ...

  8. stdarg.h头文件源代码分析

    谈到C语言中可变参数函数的实现(参见C语言中可变参数函数实现原理),有一个头文件不得不谈,那就是stdarg.h 本文从minix源码中的stdarg.h头文件入手进行分析: #ifndef _STD ...

  9. CentOS 添加环境变量

      1.修改环境变量需要修改/etc/profile export PATH="$PATH:/usr/src/ruby-1.9.3-p0/ruby:/usr/local/bin/gem&qu ...

  10. H3C系列之三层交换机开启telnet管理的配置

    环境介绍>>>>>>>>>>>>>>>>>>>>交换机名牌:H3C交换机类型:三 ...