经典算法-----约瑟夫问题(C语言)

2023-10-27

 目录

前言

故事背景

约瑟夫问题

环形链表解决

 数组解决


前言

        今天我们来玩一个有意思的题目,也就是约瑟夫问题,这个问题出自于欧洲中世纪的一个故事,下面我们就去通过编程的方式来解决这个有趣的问题,一起来看看吧!

故事背景

        据说著名犹太历史学家Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从。首先从一个人开始,越过k-2个人(因为第一个人已经被越过),并杀掉第k个人。接着,再越过k-1个人,并杀掉第k个人。这个过程沿着圆圈一直进行,直到最终只剩下一个人留下,这个人就可以继续活着。问题是,给定了和,一开始要站在什么地方才能避免被处决。Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。

        17世纪的法国数学家加斯帕在《数目的游戏问题》中讲了这样一个故事:15个教徒和15 个非教徒在深海上遇险,必须将一半的人投入海中,其余的人才能幸免于难,于是想了一个办法:30个人围成一圆圈,从第一个人开始依次报数,每数到第九个人就将他扔入大海,如此循环进行直到仅余15个人为止。问怎样排法,才能使每次投入大海的都是非教徒。

约瑟夫问题

从键盘获取两个数据,n和s,n是表示人数,s是表示从第一个人开始数,数到第s个的时候那个人就出局,问:最后剩下的最后一个人是第几个?

环形链表解决

        这里我们可以去通过环形链表的形式来解决这个问题 ,过程图如下所示:

先根据当前输入的人数去创建一个相对应的环形链表,依次把每个人的位置存入进去

 然后就去从第一个人开始数,当数到第三个人的时候就进行删除操作,如下所示,后面就从第四个节点开始新的一轮……

代码如下所示: 

#include <stdio.h>
#include<stdlib.h>
//节点
typedef struct node {
	int num;
	struct node* next;
}Node;

//创建一个环形链表
Node* create_list(int n) {
	Node* head, * tail;
	head = tail = NULL;
	for (int i = 0; i < n; i++) {
		Node* p = (Node*)malloc(sizeof(Node));
		p->num = i + 1;    //依次标记当前位置
		if (head == NULL) {
			head = p;
			tail = p;
			head->next = NULL;
		}
		else
		{
			tail->next = p;
			tail = p;
		}
		tail->next = head;
	}
	return head;  //返回头结点
}

int main() {
	int n, s;
	printf("请输入:");
	scanf("%d %d", &n, &s);
	Node* cur = create_list(n);
	int count = 1; //此时cur指向的是第一个节点,所以count为1
	while (n != 1) {	//当n=1时候,结束循环,此时剩下最后一个人
		count++;//先进行count统计
		if (count == s) {
			n--;	
			//进行删除节点操作
			Node* del_node = cur->next;	
			cur->next = del_node->next;
			free(del_node);//释放掉这个节点
			//此时count回归到1,也就是重新开始新的一轮
			count = 1;
		}
		cur = cur->next;
	}
	printf("最后剩下的是:%d\n", cur->num);
}

 数组解决

         不同与链表的是,数组不能去自定义人的数量,也就是说这里数组的数量是提前写好了的,还有就是数组的执行效率更加高,环形链表要去通过遍历执行,时间复杂度为O(n),而数组可以去直接找到这个位置时间复杂度为O(1),不需要去一个一个遍历,代码如下:

//数组实现
#include<stdio.h>
void function(int* num, int length, int s, int start) {
	int count = 0;
	int i = start - 1;//标记起始位置
	int n = length;	//当前人数
	while (n != 1) {
		i = (i + s - 1) % n;	//下一个出局人的位置
		for (int j = i + 1; j < length; j++)
			num[j - 1] = num[j];	//进行删除操作,把要删除的数字后面的依次往前移动,覆盖掉这个要删除的数字
		n--;//删除操作完成,减少一个人
		if (i == n) {	//当i超出数组范围的时候,i就回归到第一个为止
			i = 0;
		}
	}
	printf("最后一个 :%d", num[i]);
	return;
}

int main() {
	int num[6];//这里就已经定义好了6个人
	int s;	//每次数到s,出局一个
	printf("请输入:");
	scanf("%d", &s);
	for (int i = 0; i < sizeof(num) / sizeof(int); i++)
		num[i] = i+1;
	function(num, sizeof(num) / sizeof(int), s, 0);
}

以上就是今天的内容,我们下次见!

分享一张壁纸:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

经典算法-----约瑟夫问题(C语言) 的相关文章

随机推荐

  • 【转载】CSS3之Clip(裁剪)拓展阅读

    Clip属性是大家经常会误解的一个属性 这篇文章帮助大家充分的了解和学习clip属性 用这个属性制作出更好的效果 我可以确定Clip属性有很多同学并不知道 因为这个属性使用率非常的底 我初次接触是在Drupal的主题之中 他们有一段用来隐藏
  • 人才管理是什么意思_复合型人才是什么意思(复合型人才八种能力)

    有人经常会这样想 自己专业性知识很扎实 可为啥还是找不到满意的工作 原文来自www 777n com 复合型人才 自媒体www 777n com 对 一个优秀的企业在决定是否录用你 考虑的肯定不只是一点 学历 专业知识 工作经验等等方面 企
  • ios post上传文件到服务器,iOS 使用Post方法上传文件或图片

    在iOS开发中使用POST请求上传文件分为三步 1 设置请求行 NSURL url NSURL URLWithString NSString stringWithFormat 2 设置post请求 post请求抽出到NSMutableURL
  • 比较两个set是否相等?(C++)

    假设有两个set如下 include
  • Python中数据类型和变量的使用

    常用数据类型 计算机能处理的远远不止数值 还可以处理文本 图形 音频 视频 网页等各种各样的数据 而处理不同的数据 需要使用不同的数据类型来进行表示 数字型 整型 int 浮点型 float 复数 complex 布尔型 bool 只有两个
  • Ubuntu 安装 Samba 服务器

    1 Ubuntu 安装 Samba 服务器 确认安装 dpkg l grep samba 安装 sudo apt get install samba samba common 卸载 sudo apt get autoremove samba
  • 【YOLOv7/v5系列算法改进NO.46】融合DLinkNet模型中协同双注意力机制CDAM2

    文章目录 前言 一 解决问题 二 基本原理 三 改进办法 前言 作为当前先进的深度学习目标检测算法YOLOv7 已经集合了大量的trick 但是还是有提高和改进的空间 针对具体应用场景下的检测难点 可以不同的改进方法 此后的系列文章 将重点
  • 保证分布式系统数据一致性的6种方案

    原文 http weibo com ttarticle p show id 2309403965965003062676 问题的起源 在电商等业务中 系统一般由多个独立的服务组成 如何解决分布式调用时候数据的一致性 具体业务场景如下 比如一
  • 解决pycharm中unresolved reference ‘ ’无法导入工程中的包的问题

    跑一篇论文中的代码 一直有错误 显示无法导入包 明明我的导入的包都在工程中 但当我在main py中添加trainers包时 from trainers import 会出现这种错误 经过改正 有两种方法解决 一 将 py文件全部移出src
  • 【JavaEE】多线程(二)

    多线程 二 文章目录 多线程 二 第一个多线程程序 观察线程 sleep 创建线程 继承Thread类 重写run方法 实现Runnable 重写run 继承Thread 重写run 实现Runnable 重写run 基于lambda表达式
  • 内存卡数据删除了怎么恢复?sd卡数据恢复,3个步骤找回

    sd卡就是常见的内存卡 它作为数据的存储设备之一 通常用来保存照片 音频 视频等数据 但是因为误删除或者格式化原因把里面的数据删除了怎么办 让小编来告诉你sd卡数据恢复的方法 无须再为sd卡数据丢失而烦恼了 一 sd卡数据丢失的原因 在恢复
  • 中文文本摘要提取 (文本摘要提取 有代码)基于python

    任务简介 文本摘要旨在将文本或文本集合转换为包含关键信息的简短摘要 文本摘要按照输入类型可分为单文档摘要和多文档摘要 单文档摘要从给定的一个文档中生成摘要 多文档摘要从给定的一组主题相关的文档中生成摘要 按照输出类型可分为抽取式摘要和生成式
  • 在QWidget中使用QML的控件,举一个例子

    好的 在 QWidget 中使用 QML 的控件 你需要使用 Qt Quick 的 QQuickWidget 控件 下面是一个例子 include
  • UE4 C++ 位移枚举类型

    UE4中的移位枚举 枚举经常被序列化并存储为int 一般UE4中的枚举为uint8
  • Java 补全两个年份之间缺失的年份\计算两个日期相差年数

    计算两个日期相差年数 public static int yearDateDiff Date startDate Date endDate Calendar calBegin Calendar getInstance 获取日历实例 Cale
  • mysql远程同步数据表_关于MYSQL的远程数据库表间同步的构思与测试

    关于MYSQL的远程数据库表间同步的构思与测试 前沿 由于业务需求 客户需要同步一个数据库部分表到另外一台服务器上 使用mysql日志复制方案行不通 只能从mysql触发器 mysql的 federated引擎来解决 第一 打开Mysql的
  • 木桶布局 原理与实现

    项目中有一些图片布局需要按木桶布局排列 而前端工程师是个新手 不会用JS实现 只能在后端处理 直接返回处理好的图片尺寸 达到木桶布局的效果 木桶布局就是将图片按行 等高排列 并且保证每一行图片排列正好占满 边距相等 效果如下 实现木桶布局的
  • strptime、strftime的区别

    strptime p表示parse 表示分析的意思 所以strptime是给定一个时间字符串和分析模式 返回一个时间对象 strftime f表示format 表示格式化 和strptime正好相反 要求给一个时间对象和输出格式 返回一个时
  • zookeeper - 集群搭建(一)

    1 三台虚机为例 10 180 0 21 10 180 0 22 10 180 0 23 2 分别创建三台虚机机 虚拟机创建参考文档 https blog csdn net duanlei123456 article details 878
  • 经典算法-----约瑟夫问题(C语言)

    目录 前言 故事背景 约瑟夫问题 环形链表解决 数组解决 前言 今天我们来玩一个有意思的题目 也就是约瑟夫问题 这个问题出自于欧洲中世纪的一个故事 下面我们就去通过编程的方式来解决这个有趣的问题 一起来看看吧 故事背景 据说著名犹太历史学家