【模拟链表】Joseph

Joseph问题的递推公式解法 Joseph问题是算法领域的一个经典问题,虽然其抽象意义很简单,但曾被改变成各种千奇百怪的、貌似具有“故事性”的问题,被各高校(或许还包括一些特殊的中学)的数据结构课程或者算法课程的老师作为作业布置给学生们。 Joseph问题,音译为“约瑟夫问题”,大意是N个人排成一个环,按顺时针(或逆时针)编号0,1,2,...,N-1,从编号为0的人开始从1报数,报到M的人就出列,出列者的下一个人从1开始继续 阅读详情

Joseph

 

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1652    Accepted Submission(s): 1031

 

 

Problem Description

The Joseph's problem is notoriously known. For those who are not familiar with the original problem: from among n people, numbered 1, 2, . . ., n, standing in circle every mth is going to be executed and only the life of the last remaining person will be saved. Joseph was smart enough to choose the position of the last remaining person, thus saving his life to give us the message about the incident. For example when n = 6 and m = 5 then the people will be executed in the order 5, 4, 6, 2, 3 and 1 will be saved.

Suppose that there are k good guys and k bad guys. In the circle the first k are good guys and the last k bad guys. You have to determine such minimal m that all the bad guys will be executed before the first good guy. 

 

 

Input

The input file consists of separate lines containing k. The last line in the input file contains 0. You can suppose that 0 < k < 14. 

 

 

Output

The output file will consist of separate lines containing m corresponding to k in the input file. 

 

 

Sample Input


 

3 4 0

 

 

Sample Output


 

5 30

 

思路:

如果用c++STL的list做这题的话,会超时,目前没有想到怎么用list在AC这题,这里用的方法是模拟一个链表的过程,思路简单来说就是逐个枚举 m 的值,直到满足条件就输出 m ,但是如果用list的话,每删除一个list元素,就要整个list遍历一遍,一般上了千次的遍历,耗时都会很大,所以,不超时的方法就是跳过遍历,直接通过找出+ m 之后的元素,然后删除,每枚举一个 m 值得时候,就只需要遍历  k个元素就行了,时间会快很多;还有另外一个要注意的地方,以后出现类似的题要有习惯性的添加一个打表 的数组,避免判定机多次输入时间超时,下面给出代码(代码下面会给出模拟的方法)

#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<time.h>
#include<cmath>
#include<stack>
#include<list>
#include<queue>
#include<map>
#define E exp(1)
#define PI acos(-1)
#define mod (ll)(1e9+9)
#define INF 0x3f3f3f3f;
//#define _CRT_SECURE_NO_WARNINGS
//#define LOCAL
using namespace std;

typedef long long ll;
typedef long double lb;


int main(void)
{
#ifdef LOCAL
	freopen("data.in.txt", "r", stdin);
	freopen("data.out.txt", "w", stdout);
#endif
	//上面的内容可以忽视,是做题备用的代码
	int k,tp, cnt, num, flag, table[15];
	memset(table, 0, sizeof(table));

	while (scanf("%d", &k) != EOF) {
		if (k == 0) break;

		if (table[k] != 0) {       //打表的数组,就是把求出的答案保存下来,
			printf("%d\n", table[k]); //判定机测下一多组数据,如果是求过的数据 
			continue;				//的话可以直接输出
		}

		int m = k + 1, cur;
		//  这里并没用到什么跟链表有关的内容,只是在for循环的尾部,
		//加了一个 if(到最尾数值)  让 i = 0 重新在遍历一遍,
		//这样就能像遍历链表一样了  
		while (1) {
			num = 2 * k ; flag = 0; cur = 1;
			while (num > k) {
				// 这个tp的值是当前遍历到的值 cur 继续报数的次数,
				//其实 tp换成m是没有什么问题的,
				//只是,m的值一旦大起来,就会很耗时
				//比如说 m = 10 要在一个有6个元素的数组报数,
				//报10次和报4次的结果是一样的,  
				tp = m % num == 0 ? num : m % num;	 

				//这里的 下一个cur的值是通过两种情况求的, 第一种是报了tp次数后
				//没有超过目前有的元素的个数,就可以直接 +tp
				// 如果超过了,就通过 互补的关系求得 下一个cur
				if (cur + tp - 1 > num) {			
					cur = tp - (num - cur)-1;	//互补关系求的cur
				}									
														
				else cur = cur + tp - 1;

					if (cur <= k) {
						flag = 1;
						break;
					}
					else num--;
				}
			if (flag) {
				m++;
				//这里是枚举m的时候的一个剪枝代码,如果第一次报数的结果
				//小于或等于K的值,那这个数就不必要去试了,直接把目前枚举的值
				//加到大于k的值然后去试 
				if (m % (2 * k) <= k && m % (2 * k) != 0) { 
					m += (k - m % (2 * k) + 1);			
				}
			}
			else{
				table[k] = m;
				printf("%d\n", m);
				break;
			}
		}
	}	
	//system("pause");
	return 0;
}

这里模拟的过程大概是这样的:

当 m = 5 , k = 3 的时候

1 2 3 4 5 6  报数5 之后,按照链表的手法是删除5这个元素,但这里并不是,而是把 5 这个位置让给 6 来做

结果是这样的:

1 2 3 4 5   

那么目前元素有5个,根据代码里的方法求 tp  然后从 5 这个元素开始报数, cur将会是  4 这个元素,那么 4 这个元素的位置就让 5 (就是要删除的这个元素的上一个)来做,删除的过程很简单,就是在遍历的前设置一个  num = 2*k; 只要num--就能不用继续遍历大于num的数组的数字;

然后结果是  1 2 3 4 ,继续报数,最后得到cur =3,这个时候 num==k  那么就可以退出循环了;

 

 

 

Joseph环求解算法的设计与实现 Joseph环求解算法的设计与实现@TOC 1.实验内容 约瑟夫(Joseph)问题的一种描述是:编号为1,2,…,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人全部出列为止。试设计一... 阅读详情

相关推荐

遥感图像小白--2--图像分割

遥感图像分割基础入门

Mary的博客 4237

算法学习 2.5——模拟链表

模拟链表是链表的另一种表示方式,不使用指针。 (但指针的操作的确方便快捷,如果实在搞不懂指针实现链表的朋友就算了) 什么是模拟链表呢,经过上一节的学习我们知道链表是通过节点的指针指向下一个节点的地址,所谓地址可不可以模拟成位置呢? 仔细想一想,往下看 —————————————————————————————————— 既然链表中的节点分为数据和指针地址,那么我们可不可以使用两个数组,一个数组用来存放数据,另一个数组用来存放地址呢。 存放什么地址合适?这里的地址我们可以看成位置,链表中的节点指针存放的是下一

qq_44905854的博客 362

阿里云CDN HTTPS 证书配置流程

可以使用HTTPS方式访问资源,如果浏览器中URL旁边出现锁的HTTPS标识,表示HTTPS安全加速已生效。: 证书配置完成后,需要留意证书过期时间并在证书过期前手动配置新的证书。注意 ⚠️ 一定是需要复制 以下标识之间的内容。如果已在阿里云数字证书管理服务中购买了证书,请选择。,该证书将在阿里云数字证书管理服务中保存。如果使用第三方服务商签发的证书,请选择。第四步,在指定域名的左侧导航栏,单击。第二步,在左侧导航栏,单击。开关,并配置证书相关参数。页面,找到目标域名,单击。中选择已购买的证书。

w风雨无阻w的专栏 2210

hdu1443(约瑟夫环游戏的原理 用链表过的)

Problem Description The Joseph's problem is notoriously known. For those who are not familiar with the original problem: from among n people, numbered 1, 2, . . ., n, standing in circle every mth is

青山绿水之辈 专栏 1778

手把手教你学simulink(31.17)--双向DCDC电源场景示例:基于simulink 的双向DCDC应用:车载充电器的pi控制

通过引入PI控制器,系统可以更精确地控制电压和电流,确保充电和放电过程的稳定性和高效性。

MHD0815的博客 205

【Bluetooth蓝牙开发】一、开篇词 | 打造全网最详细的Bluetooth开发教程

1、开篇词 2、蓝牙开发入门 3、蓝牙协议栈总览 4、蓝牙协议栈——物理层 5、蓝牙协议栈——链路层 6、蓝牙协议栈——传输层 7、蓝牙协议栈——L2CAP协议 8、蓝牙协议栈——ATT协议 9、蓝牙协议栈——GATT协议 10、蓝牙通信流程分析 11、蓝牙协议栈——Bluez交叉编译 12、蓝牙调试工具汇总

Donge's Blog 1万+

Josephu问题链表方法

Josephu问题:编号为0到N-1的N个人围成一圈,然后从1开始报数,报到M的那个人被杀掉,剩下的人接着从1开始报数,求最后的幸存者编号。 前面给出了该问题的数学解法,下面贴上链表方法,直接模拟整个过程。 #include #include struct node { int num; struct node *next; }; typedef struct node

愤怒的小草 979

量子化学仿真软件:VASP_(7).表面与界面性质模拟

在量子化学仿真软件领域,表面与界面性质的模拟是研究多相催化、表面反应、材料科学等领域的关键工具。VASP(Vienna Ab Initio Simulation Package)作为一种广泛使用的密度泛函理论(DFT)计算软件,提供了强大的功能来模拟表面与界面的性质。本节将详细介绍如何使用VASP进行表面与界面性质的模拟,包括模型构建、输入文件准备、计算设置、结果分析等步骤。

kkchenjj的博客 951

模拟链表

    在我的上一篇博客中,我们用到了有序链表。但是有些人,就会说,我目前还看不懂指针,就是不知道指针该怎么使用,那么我在《啊哈!算法》中学到了另一个方法,就是模拟链表。     在该方法中,我们将会定义两个数组,一个为data,另一个为right。 data数组用来存放真正的元素或数字,right数组用来存放data数组中每一个数的右边是谁(此处的意义跟链表中Next指针一样)。     那...

Gerald的博客 534

11 指挥AI写C语言/嵌入式基础代码,适配硬件与底层逻辑

本文为《30天掌控AI编程:从指令到落地,手把手教你指挥AI写代码》系列第十一篇,正式进入第三阶段多场景实战环节。聚焦**C语言/嵌入式基础代码**生成,结合嵌入式开发的核心需求,讲解如何精准编写指令,指挥AI生成适配硬件、贴合底层逻辑的C语言代码,覆盖嵌入式常用底层功能、硬件适配要点、代码规范,搭配完整指令模板、AI输出示例与实操校验方法,零基础也能快速指挥AI完成嵌入式基础开发,无需死记硬背C语言底层语法。

coreopt的博客 140

把 OData V4 服务真正发布出去:事务码 /IWFND/V4_ADMIN 在 SAP S/4HANA On-Premise 里的定位与用法

本文介绍了SAP S/4HANA中的事务码/IWFND/V4_ADMIN,这是SAP Gateway管理OData V4服务的关键工具。该事务码主要负责将后端注册的OData V4服务以服务组形式发布到前端,并维护系统别名路由、测试入口和日志跳转。与OData V2不同,V4采用服务组概念以支持跨服务导航,类似商场统一管理多个专柜。文章还通过实际案例说明,未发布服务组会导致BAS等工具无法发现OData V4服务,并提供了验证服务组状态的访问路径和ABAP示例代码。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 208

Joseph问题

<!-- html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, str

Room of Requirement 1164

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

POJ 1012 Joseph

POJ 1012 Joseph 算法解析:本来我想用链表或者数组来模拟这个Joseph链,后来发现因为题目并没有要求输出每一次报数排除的人的号码且前k个人是好人不能被排除,因此不需要那么复杂的模拟,仅需要每次剔除一个人以后重新组成Joseph链(可以看成我们不关心每个人起初对应的号码是多少,只关心现在链中有多少人及现在报数的位置);另外需要注意的是报数m仅仅可能是m%(k+1)=0 或1

BlackLillian的专栏 616

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

android 蓝牙通讯demo

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

joseph环

Joseph环 joseph环是对于循环链表的应用,分为三部分:创建循环链表、应用规则、组装 typedef struct node{ /* data */ int No; /*游戏者的编号*/ unsigned int Pwd; /*游戏者的密码*/ struct node *next; }Node,*LinkList; 创建循环链表 LinkList creat_list(int n){ LinkList p,r;//p创建的结点 r未知 int i;

qq_39985775的博客 571

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

数据结构-joseph环

////joseph环 //时间:05/07/04 //程序:张建波 //输入 n=7 // 3,1,7,2,4,7,4 //输出6 7 4 1 5 3 2 #include &lt;iostream.h&gt; #include "key.h" typedef struct person { int pwd; //密码 int num; //人数 struct person...

huobengle 390

数据结构-约瑟夫环的简单实现(循环链表)

闲来无事,突然想起了大学期间数据结构的一些小游戏,就实现下自己以前做过的东西,这次选的是Joseph环,呵呵,这也是我第一次写东西,有不妥的地方希望大家多多包涵。目的就是帮助刚接触数据结构的学弟学妹们,不多少了,直接上代码了吧。#include #include typedef struct link { int data; struct link *next; }link_node, *link_list; /*初始化循环链表*/ link_list init() { r

app_jxnu的专栏 2360

poj1012 Joseph题解2

<br />之前用链表模拟了Joseph环,但是代码非常的长。<br />poj1012 Joseph题解:http://blog.youkuaiyun.com/Justmeh/archive/2010/08/11/5803590.aspx<br />我们注意到题目中并没有要求我们求出最后的剩余的人是第几个,所以与经典的Joseph环还是太一样,我们根本用不着用链表来模拟。只需要一个记录剩余环中的人数的变量即可,这样代码简洁多了,如下:<br />#include<iostream> #include<vector>

he-honghua的专栏 1049

Joseph问题(循环链表)

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

delaoguai7289的博客 241

joseph问题

Joseph问题1.Joseph描述:2.instance analysis 1.Joseph描述: 原始的Joseph问题的描述如下:有n个人围坐在一个圆桌周围,把这n个人依次编号为1,…,n。从编号是start的人开始报数,数到第num个人出列,然后从出列的下一个人重新开始报数,数到第num个人又出列,…,如此反复直到所有的人全部出列为止。比如当n=6,start=1,num=5的时候,出列的顺序依次是5,4,6,2,3,1。 2.instance analysis #include <stdio

嵌入式与人工智能 852

一道Joseph环问题

一道Joseph环问题题意简述题目分析代码 在学校寒假搞的算法天梯中遇到的一个Joseph环的问题,题目如下。 题意简述 n 个人组成一个环,选一个起点从1-n编号,两位老师分别从1 号和 n 号沿着顺时针和逆时针方向计数,第一个老师计数到 k 时停下,第二个老师计数到 m 时停下,如果停下的位置不一样,那么请这两个人出环,并输出他们的原始编号,并继续清点,如果一样,那么输出这个位置的人的原始编号,结束清点,环已经空了,也结束清点。 数据范围:1 <= n <= 30000,m,k 都在 i

WA_PRODUCER的博客 240

一道模拟题:改进的Joseph环

题目:改进的Joseph环。一圈人报数,报数上限依次为3,7,11,19,循环进行,直到所有人出列完毕。 思路:双向循环链表模拟。 代码: 1 #include <cstdio> 2 #include <cstdlib> 3 4 #define N 20 5 6 typedef struct node 7 { 8 int ...

weixin_30909575的博客 119
上一篇: list在圆桌问题循环遍历弹出的两个问题
下一篇: ZOJ 3203 Light Bulb (三分)
Y390d
博客等级 码龄9年 11粉丝 165原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值