约瑟夫问题求解

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

约瑟夫(Josephus)问题:n个人围城一圈,从1开始顺序编号;游戏开始,从第一个人开始由1到m循环报数,报到m的人退出圈外,问最后留下的那个人原来的序号。

解法(1):

求解思路:首先定义一个n大小的数组,数组中存标识符,1表示在圈内,0标识出局,初始化都为1。当开始报数的时候,设一个计数器,记录当前已经报的人数,如果某人标识符为1,则报数;为0,则跳过,直到报完数为止。

代码如下,时间复杂度为O(mn)

#include<iostream>
using namespace std;
int main()
{   
	int beginposition=0;
	int length=0;
	int count;
	int n,m;
	cout<<"please input N M"<<endl;
	cin>>n>>m;
	const int N=n;
	int *p=new int[n];
	for(int i=0;i<n;i++)
	{
		p[i]=1;
	}
	while(n>1)
	{
		count=0;
		length=m%n;
		if(length==0) length=n;
		for(int i=0;i<N;i++)
		{
			if(p[beginposition]==1) count++;
			if(count==length)
			{
				p[beginposition]=0;
				beginposition=(beginposition+1)%N;
				n--;
				break;
			}
			beginposition=(beginposition+1)%N;
		}
	}
		for(int i=0;i<N;i++)
		{
			if(p[i]==1) cout<<i+1<<endl;
		}
	system("pause");
	return 0;
}
解法(2):转自http://www.cnblogs.com/EricYang/archive/2009/09/04/1560478.html

为了讨论方便,先把问题稍微改变一下,并不影响原意:
问题描述:n个人(编号0~(n-1)),从0开始报数,报到(m-1)的退出,剩下的人继续从0开始报数。求胜利者的编号。

我们知道第一个人(编号一定是m%n-1) 出列之后,剩下的n-1个人组成了一个新的约瑟夫环(以编号为k=m%n的人开始):
  k  k+1  k+2  ... n-2, n-1, 0, 1, 2, ... k-2并且从k开始报0。
现在我们把他们的编号做一下转换:

k     --> 0
k+1   --> 1
k+2   --> 2
...
...
k-2   --> n-2
k-1   --> n-1
变换后就完完全全成为了(n-1)个人报数的子问题,假如我们知道这个子问题的解:例如x是最终的胜利者,那么根据上面这个表把这个x变回去不刚好就是n个人情况的解吗?!!变回去的公式很简单,相信大家都可以推出来:x'=(x+k)%n

如何知道(n-1)个人报数的问题的解?对,只要知道(n-2)个人的解就行了。(n-2)个人的解呢?当然是先求(n-3)的情况 ---- 这显然就是一个倒推问题!好了,思路出来了,下面写递推公式:

令f[i]表示i个人玩游戏报m退出最后胜利者的编号,最后的结果自然是f[n]

递推公式
f[1]=0;
f[i]=(f[i-1]+m)%i;  (i>1)

有了这个公式,我们要做的就是从1-n顺序算出f[i]的数值,最后结果是f[n]。因为实际生活中编号总是从1开始,我们输出f[n]+1
由于是逐级递推,不需要保存每个f[i],程序也是异常简单:

#include <stdio.h>
int main()
{
    int n, m, i, s = 0;
    printf ("N M = ");
    scanf("%d%d", &n, &m);
    for (i = 2; i <= n; i++)
    {
        s = (s + m) % i;
    }
    printf ("\nThe winner is %d\n", s+1);
}


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

相关推荐

帆软FineBI考试题

Flint 补录表,有批次删除功能。在分析主题内添加数据时能够选择批量添加数据。插件安装过程中有报错提示需要下载 Fine I for Excel 运行环境进行修复,修复完毕后重新安装插件。图例显示支持自定义设置,且图例标题支持隐藏显示。finebi中的指标如果想进行维度区间/真的自定义分组,不能直接拖拽到组建区域中需要先转化为维度方可进行指标分组。excel报表不支持分页。

Davina_yu的博客 1593

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

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

m0_73355263的博客 1万+

新出的智谱GLM-4.7很牛逼?

Zhipu AI(智谱)最近发布的 GLM-4.7 再次刷新了开源大模型的天花板。作为一款约 400B 参数规模的 MoE 模型,它不仅在传统的代码与推理任务上超越了 DeepSeek-V3.2 和 Kimi-K2 等强力对手,更通过**“保留思考(Preserved Thinking)”和“交错思考(Interleaved Thinking)”**等架构级创新,重新定义了 Agentic Workflow 的设计范式。

kakaZhui的博客 2387

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

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

浪子回头 4609

从交换机安全配置,看常见局域网攻击

前言 构建零信任网络,自然离不开网络准入(NAC),这就涉及到交换机的一些安全测试,于是有了此文《从交换机安全配置看常见局域网攻击》。 交换机安全配置 如本文标题所说从交换机安全配置看常见的局域网攻击,那么下面提到的各种攻击方式,自然是建立在交换机安全配置之上来说的。我们通过h3c官方提供的《H3C 交换机安全加固手册》和《安全配置指导》,从这两份手册可以看出交换机支持的安全配置非常多,基本已经覆盖了各种我们熟知局域网攻击。下面就挑几个典型的攻击方式进行演示。 arp欺骗 【一>所有资源获取&lt

kali_Ma的博客 1万+

gnss变形监测基础(四)

监测站的数据采样率指的是监测站在单位时间内收集数据的频率,通常以赫兹(Hz)为单位。在GNSS变形监测中,数据采样率决定了监测系统能够捕捉到的变形动态变化的详细程度和时间分辨率。例如,一个采样率为1Hz的GNSS监测站意味着它每秒钟收集一次位置数据;而一个采样率为10Hz的监测站则每秒钟收集10次位置数据。较高的采样率能够提供更细致的时间序列数据,有助于分析快速变化的动态过程,如地震活动或建筑物的振动响应。然而,较高的采样率也意味着数据量更大,可能需要更多的存储空间和更强大的数据处理能力。

我的博客 1284

约瑟夫问题的几种解决方法

约瑟夫问题的几种解决方法

weixin_58473601的博客 3418

Multisim实战:从零搭建体温检测报警电路(附完整仿真文件+调试技巧)

本文详细介绍了如何使用Multisim从零搭建体温检测报警电路,涵盖LM35温度传感器、LM358运算放大器等核心器件的选型与连接,以及信号调理、阈值比较和数码管显示等关键电路设计。附赠完整仿真文件和实用调试技巧,帮助电子工程初学者快速掌握体温温度检测系统的设计与实现。

weixin_28285943的博客 289

约瑟夫(Josephus)问题的求解——利用循环链表

约瑟夫(Josephus)问题的求解——利用循环链表 1. 约瑟夫问题的提法 约瑟夫问题(约瑟夫环)是一个数学的应用问题。 已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围,从编号为k的人开始报数,数到m的那个人出列,他的下一个人又从1开始报数,数到m的那个人又出列,依此规律重复下去,直到圆桌周围的人全部出列。 通常解决这类问题时我们把编号从1~n,最后结果编号即为原问题的解。 2. 求解约瑟夫问题的

Catherine的笔记 9365

KNN算法

其原理是在给定的数据集中,根据某个距离度量方法,将测试数据与已知数据集中的所有数据进行距离计算,然后选取K个距离最近的数据作为测试数据的邻居,根据邻居的类别进行投票,将测试数据分类到得票最多的类别中。总之,KNN算法是一种简单而有效的分类方法,它不需要对数据进行训练,可以适用于多种数据类型和应用场景,并且可以通过调整K值或距离阈值等参数来控制算法的复杂度和性能。,KNN算法需要找到K个距离测试样本最近的训练样本,计算它们的类别,并将测试样本归入到得票最多的类别中。则取值为1,否则为0,表示邻居中属于类别。

CSDNXXCQ的博客 2623

2、TrustZone(内含链接)——长期学习内容

ARM系列学习路径整理,希望对大家有用。

HoneyIC的博客 229

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

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

clear_king的博客 435

RockChip Android14 修改LCD背光最大值

在调试LCD屏时时长会出现硬件不匹配,导致电流过大,屏幕发热严重。在不调整硬件的情况下,我们可以通过修改软件,降低LCD背光最大值来实现适配。我们都知道LCD屏背光是靠pwm来控制,一般来说最大值可以设置为255,针对上述问题,我们可以通过软件来降低该值,比如200,100等等。

qq_34968572的博客 627

约瑟夫问题及求解方法

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

z135733的博客 3688

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

VC中sqlite的使用

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

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

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

z939188380的博客 1328

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

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的博客 321

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

约瑟夫问题三种求解方法

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

hb2008hahaha的专栏 3096

约瑟夫问题 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的博客 510

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

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

rocky_56X的博客 505

约瑟夫问题的求解!

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

448

约瑟夫问题 求解过程的另一种容易理解方式

从华为在重邮的一道机试题

hntyzhangpeng的专栏 672
上一篇: void *的那些事
下一篇: 【LEETCODE】Implement strStr().
Strugoogle
博客等级 码龄12年 0粉丝 9原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值