约瑟夫问题求解

用循环队列求解约瑟夫环问题 用循环队列求解约瑟夫环问题 大家好,这次我们来求解求解约瑟夫环问题,并对比用循环队列和用普通形式求解之间的不同之处。也欢迎各位大佬指正。 目录如下可快速查阅问题描述循环队列求解算法描述程序清单运行结果普通形式求解算法描述程序清单运行结果对比分析 问题描述 设有n个人站成一圈,其编号为1~n。从编号为1的人开始按顺时针方向1、2……循环报数,数到m的人出列,然后从出列者的下一个人重新开始报数,数到m... 阅读详情

问题描述:

据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从,Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。
17世纪的法国数学家加斯帕在《数目的游戏问题》中讲了这样一个故事:15个教徒和15 个非教徒在深海上遇险,必须将一半的人投入海中,其余的人才能幸免于难,于是想了一个办法:30个人围成一圆圈,从第一个人开始依次报数,每数到第九个人就将他扔入大海,如此循环进行直到仅余15个人为止。问怎样排法,才能使每次投入大海的都是非教徒。
*问题分析与算法设计
约瑟夫问题并不难,但求解的方法很多;题目的变化形式也很多。这里给出一种实现方法。
题目中30个人围成一圈,因而启发我们用一个循环的链来表示。可以使用结构数组来构成一个循环链。结构中有两个成员,其一为指向下一个人的指针,以构成环形的链;其二为该人是否被扔下海的标记,为1表示还在船上。从第一个人开始对还未扔下海的人进行计数,每数到9时,将结构中的标记改为0,表示该人已被扔下海了。这样循环计数直到有15个人被扔下海为止。


//author openxmpp@163.com

#include <iostream>
using namespace std;
#include <unistd.h>

template<typename T>
class Node
{
    template<typename U> friend Node<U>*  makeList( U start , U end );
    template<typename U> friend Node<U>*  removeNodeBySteps ( Node<U> * list, int steps );
    template<typename U> friend bool testJosephusLoop ( Node<U> * list );
public:
    Node<T> (T &value);
    Node<T> *getNext();
    T & getValue ();
private:
    Node *mNextNode ;
    T mValue;
};

template<typename T>
Node<T>::Node(T &value)
{
    mValue = value;
}

template<typename T>
Node<T> *
Node<T>::getNext()
{
    return mNextNode;
}

template<typename T>
T &
Node<T>::getValue()
{
    return mValue;
}

template<typename T>
Node<T> *
makeList(T start, T end)
{
    Node<T> * firstNode = 0;
    Node<T> * lastNode = 0;
    Node<T> * currentNode = 0;
    for ( T loop = start ; loop < end ; loop ++ )
    {
        if ( loop == start )
        {
            firstNode = new Node<T>(loop);
            currentNode = firstNode;
            continue;
        }
        else if ( loop < end )
        {
            Node<T> *tmpNode = new Node<T>(loop);
            currentNode -> mNextNode = tmpNode;
            currentNode = tmpNode;
        }
    }
    lastNode = new Node<T>(end);
    currentNode -> mNextNode = lastNode;
    lastNode -> mNextNode = firstNode;
    return lastNode;
}

template<typename U>
Node<U>*
removeNodeBySteps ( Node<U> * list, int steps )
{
    int cnt = 0;
    while ( true )
    {
        if ( list -> mNextNode == list )
        {
            cout << " the WINNER is  " << list->mValue << endl ;
            return list;
        }
        else
        {
            if ( cnt == steps - 1 )
            {
                Node<U> *nextNode = list->mNextNode;
                cout << " the player is out " << nextNode->mValue << endl;
                list->mNextNode = nextNode->mNextNode;
                delete nextNode ;
                nextNode = 0;
                cnt = 0 ;
            }
            else
            {
                cnt ++ ;
                    list = list->mNextNode ;
            }
        }
    }
}

template<typename U>
bool
testJosephusLoop( Node<U> * list )
{
    if ( 0 == list )
    {
        return false;
    }
    Node<U> * firstNode = list ;
    while ( true )
    {
        if ( list->mNextNode == firstNode )
        {
            return true;
        }
        else if ( list && list->mNextNode )
        {
            list = list -> mNextNode;
        }
        else if ( list || list->mNextNode )
        {
            return false;
        }
    }
    return false;
}

void uniTest()
{
    Node<int> * result = makeList(1,9);
    bool check = testJosephusLoop(result);
    cout << "check result "<< check	<<endl;
    removeNodeBySteps<int>(result,5);

    Node<long> * result2 = makeList<long>(10,20);
    bool check2 = testJosephusLoop(result2);
    removeNodeBySteps(result2,3);
}

int main(int argc, char const *argv[])
{
    uniTest();
    return 0;
}


约瑟夫斯问题的求解方法 约瑟夫斯问题 1. 问题介绍   这个问题是以弗拉瓦斯 约瑟夫斯的名字命名的。约瑟夫斯是一个著名的犹太历史学家,参加并记录了公元66-70年的犹太人反抗罗马的起义。约瑟夫斯作为一个将军,设法守住了裘达伯特的堡垒达47天之久,但在城市陷落之后,他在和40名顽强的战士在附近的一个洞穴中避难。在那里,一些反抗者表决说“要投降毋宁死”。于是,约瑟夫斯建议每个人应该轮流杀死他旁边的人,而这个顺序是是由抽签决... 阅读详情

相关推荐

约瑟夫问题代码

主要是使用循环链表实现,代码简单易懂。 题目中30个人围成一圈,因而启发我们用一个循环的链来表示,可以使用结构数组来构成一个循环链。结构中有两个成员,其一为指向下一个人的指针,以构成环形的链;其二为该人是否被扔下海的标记,为1表示还在船上。从第一个人开始对还未扔下海的人进行计数,每数到9时,将结构中的标记改为0,表示该人已被扔下海了。这样循环计数直到有15个人被扔下海为止。

约瑟夫问题

约瑟夫问题的来历 据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从,Jos...

weixin_30800987的博客 160

Python实战:用jieba和WordCloud打造电商评论情感分析工具(附完整代码)

本文详细介绍了如何使用Python的jieba分词和WordCloud库构建电商评论情感分析工具,涵盖数据预处理、情感分析、可视化展示等关键步骤,并提供完整代码实现。通过该工具,开发者可以高效分析电商评论数据,挖掘消费者情感倾向,为产品改进和决策提供数据支持。

weixin_30316097的博客 413

4种方法解决约瑟夫环问题

本篇文章我们总结了关于约瑟夫环问题的几种解法,它们各有优势,读者可以根据实际需要自行选择。好的问题可以引发学习者的思考,寻找更优解可以让攀登者更上一层楼。希望本篇文章能对你有所帮助,我们共勉。

m0_73355263的博客 1万+

攻克Windows平台3DGS复现:从环境配置到可视化实战全记录

本文详细记录了在Windows平台成功复现3D Gaussian Splatting(3DGS)的完整流程,涵盖从环境配置、依赖安装、数据准备到模型训练与可视化的全步骤。重点解决了Windows下CUDA版本匹配、Visual Studio编译及SIBR_viewers可视化工具部署等核心难题,为开发者提供了一份详实的避坑指南与实战手册。

weixin_28839699的博客 251

智能体在车联网中的应用:第31天 基于RLlib的多智能体PPO实战:MAPPO算法解决simple_spread合作任务

本文介绍了如何利用RLlib框架实现多智能体强化学习算法MAPPO,解决simple_spread任务。首先分析了RLlib的架构设计理念和多智能体支持特性,包括策略映射、环境包装等核心组件。然后详细解析了simple_spread环境的任务定义、观察空间和奖励函数设计。最后回顾了MAPPO算法原理,说明其如何在RLlib中实现集中式训练与分布式执行的CTDE范式。文章提供了完整的安装指南和环境配置方法,帮助读者快速搭建多智能体强化学习实验环境。

IT深耕十余载,大道之简 1332

C++约瑟夫问题的10种解法【学不会私信我】

C++约瑟夫问题的10种解法【学不会私信我】

浪子回头 4612

用逻辑分析仪实测EM4095:125kHz RFID耳标解码的电压与脉宽玄学

本文通过逻辑分析仪实测EM4095芯片,深入解析125kHz RFID耳标解码中的电压与脉宽关联现象。揭示了供电电压对曼彻斯特编码脉宽的影响规律,并提供了一套可落地的调试方法论,包括信号链路解析、逻辑分析仪配置技巧及系统级稳定性提升方案,帮助开发者解决解码不稳定问题。

weixin_30629653的博客 328

约瑟夫问题求解及进一步思考

借助数组的抽象结构,给出了约瑟夫问题的具体求解,并在此基础上对逆向求解给出了自己的思考

clear_king的博客 436

Calibre提参实战:如何用hcell和xcell文件精准屏蔽模块(附避坑指南)

本文详细解析了Calibre提参过程中hcell和xcell文件的应用技巧,帮助工程师精准屏蔽模块以优化寄生参数提取。通过对比hcell与xcell的核心差异、图形界面与命令行操作指南,以及常见问题排查方法,提升芯片后端设计效率。附避坑指南,解决EETOP论坛热议的模块丢失问题。

weixin_26795617的博客 438

十一、增强现实

那都是n年前的老版本了,新版本完全没有这个问题,我就是纠结这个问题,搭建若干环境,又是vmware虚拟机,又是msys2,又是anaconda,又是找机器,折腾了几天,结果通通不是。以一张实际卡片为锚点,通过笔记本的摄像头,在显示器上将一个计算机内的3d物体显示在卡片上,类似于电影上看到的那种全息投影技术;如果你是想在windows环境下开发linux运行程序,那么CygWin/gcc是你的不二之选。而如果你想开发的是windows运行程序,并且追求速度,那么二者相比而言,MinGW是更好的选择。

3188

约瑟夫问题及求解方法

队是一种特殊的线性表,它只允许在一端进行插入,在另一端进行删除,允许插入的一端称为队尾,通常用一个队尾指示器指向队尾元素;允许删除的一端称为排头,用一个排头指示器指向排头元素。在队列中,最先插入的元素将最先删除,因此又称队为先进先出线性表。n个人围坐在圆桌周围,从某个人开始编号为1,2,3,4,…,n,编号为1的位置上的人从1开始报数,数到m的人出列,从下一个人又从1开始报数,数到m的人便是第二个出列的人。如此重复下去,直到最后一个人出列为止。

z135733的博客 3691

【MATLAB】通过计算曲率和曲率变化率来实现对曲线波浪程度

这段代码将计算给定曲线的曲率,并与给定阈值进行比较以检测拐角。函数是MATLAB中一个常用的函数,可以用于计算曲线在每个点处的曲率。它基于一种被称为“local least squares fitting” 的方法,通过拟合每个点周围的一小段曲线来计算曲率。MATLAB中可以使用多种方法实现拐角检测,其中一种方法是基于曲率半径的算法。该算法通过计算曲线上每个点处的曲率半径,找到拐角和弯曲处。是一个可选参数,用于控制拟合曲线的平滑度,取值范围为0到1,越接近1表示曲线越平滑。表示曲线在每个点处的曲率,

Fanjufei的博客 1918

C语言中约瑟夫问题的求解思路

具体来说,在这个问题中,有 `n` 个人围成一圈,从第一个人开始报数,每报到第 `m` 个人就将其淘汰,然后从下一个人重新开始报数,直到只剩下最后一个人为止。- 如果 `count` 不等于 `m`,则只需移动 `prev` 和 `pcur` 到下一个位置,并增加计数器 `count`。- 函数 `buyNode` 用于创建一个新的链表节点,并初始化其值为 `x`,同时将下一个指针设为 `NULL`。- 最后返回尾节点 `ptail`,它的 `next` 指向头节点 `phead`,完成闭环。

z939188380的博客 1330

100:vue+cesium: 加载glb文件,随机位置加载2000架飞机

本示例在 Vue + cesium 项目中随机位置加载2000架飞机,飞机是glb文件,每个大小为571kb。这个示例属于性能优化的范畴内,通常如果用entity加载glb只能显示几个飞机,这里采用primitive的方法来加载。直接复制下面的 vue+cesium源代码,操作2分钟即可运行实现效果.

大剑师兰特的GIS世界 706

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

java求解约瑟夫问题

/** * @作者 擎宇 * @功能 约瑟夫问题求解 * @时间 2018.04.25 */package test;public class Test { public static void main(String[] args) { // TODO Auto-generated method stub Linklist linklist = new Linklist(); linkli...

qq_39996840的博客 323

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

约瑟夫问题三种求解方法

约瑟夫问题是个很经典的问题,目前网上求解方法较多,主要有数组法、循环队列法、指针链表法三种求解思路,下面给出三种求解方法的原创的标准C语言代码,含详细注释,供C语言和数据结构的初学者学习,本程序在VC 6.0下编译通过。 约瑟夫问题的来历:     据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹

hb2008hahaha的专栏 3097

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

约瑟夫问题 C++求解

约瑟夫环(Josephus)问题是由古罗马的史学家约瑟夫(Josephus)提出的,其表述方式有多种,较典型的一种是: 有n只猴子,按顺时针方向围成一圈选大王(编号从1到n),从第1号开始报数,一直数到m,数到m的猴子退出圈外,剩下的猴子再接着从1 开始报数。就这样,直到圈内只剩下一只猴子时,这个猴子就是猴王,编程求输入n,m后,输出最后猴王的编号。 解法一:数组求解 根据输入的n值确定数组的长度...

MilkLeong的博客 1万+

约瑟夫问题_顺序表求解

#include "stdio.h" #include "stdlib.h" #define MAXSIZE 100 typedef struct node { int data[MAXSIZE]; int length; }SeqList,*PSeqList; //定义一个顺序表 PSeqList Init_SeqList() //顺序表初始化 { PSeqList PL...

qqGHJ的博客 2205

约瑟夫环问题求解方法总结

约瑟夫环问题 n个人围成圈,从第一个人开始报数,数到k的人自杀。然后自杀的下一个人接着从1开始数,一直到剩下最后一个人。 一,使用队列模拟过程 首先将这n个人入队,然后开始计数,并且不断地出队,如果当前这个人是k的倍数的话就杀掉,如果不是k的倍数就再次入队。 代码如下: #include <iostream> #include <queue> using namespac...

qq_43227036的博客 511

趣味问题 约瑟夫圈的数组求解方法

假设n个人围成一个圈,从1开始报数,到3就把报数的人踢出,然后从1开始,一直循环下去,直到最后一个人,请问这个 人是第几号人? 这就是约瑟夫圈问题,这个问题的求解方法比较多,今天介绍一下它的数组求解方法。 1#include 2 int main() 3 { 4 int num = 0,out = 0,i = 0,n; //num为报号,到3清零;ou

rocky_56X的博客 507

约瑟夫问题的求解!

已知有n只猴子(以编号1,2,3,..., n 分别表示)围坐一圈。从第一只猴子开始,按顺序从1开始报数,数到 m 的那只猴子出列;接着再从从 1 开始报数,报数到 m 的那只猴子又出列;依此规律重复下,直到只剩一只猴子为止。输入n和m,输出最后剩下的猴子? 此问题,即报数问题,也是约瑟夫问题!     很多人一开始想到是用链表或数组来实现,而这都涉及到模拟整个游戏过程,要将链表或

449
上一篇: C++快速排序模板法
下一篇: sublime text2 设置空格可视化
乔巴好萌
博客等级 码龄15年 228粉丝 47原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值