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

2023-09-19 16:18:37

 目录

前言

故事背景

约瑟夫问题

环形链表解决

 数组解决


前言

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

故事背景

        据说著名犹太历史学家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);
}

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

分享一张壁纸:

更多推荐

分库分表知识点

分库分表专题1.概述1.1分库分表是什么小明是一家初创电商平台的开发人员,他负责卖家模块的功能开发,其中涉及了店铺、商品的相关业务,设计如下数据库:通过以下SQL能够获取到商品相关的店铺信息、地理区域信息SELECTp.*,r.[地理区域名称],s.[店铺名称],s.[信誉]FROM[商品信息]pLEFTJOIN[地理

【论文解读】Faster sorting algorithm

一、简要介绍基本的算法,如排序或哈希,在任何一天都被使用数万亿次。随着对计算需求的增长,这些算法的性能变得至关重要。尽管在过去的2年中已经取得了显著的进展,但进一步改进这些现有的算法路线的有效性对人类科学家和计算方法都是一个挑战。在这里,论文展示了人工智能是如何通过发现迄今为止未知的算法路线来超越目前的最先进的方法。为

你能想象在亚运赛场打《王者荣耀》吗?

作者:April叶快评:20年前,没人敢相信电竞加入亚运会,但在今年的杭州亚运会,电竞不仅正式成为官方竞赛项目,首次登场还一举成了亚运会“顶流”。你以为打游戏只会毁了你但其实打游戏也能为国争光要说今年杭州亚运会最大的“顶流”是谁那必须是这个项目不仅呼声最高门票价格也最高还是唯一要抽签才能买票的项目门票比演唱会的还难抢哪

自己实现一个简单的vhost-net

框架vhost在网络中的位置如图:要学习具体的框架可以看我之前的文章vhost-net--------深入了解Virtio-networking和vhost-net接下来,我们自己实现一个vhost.vhost-net代码在代码中写了详细注释,就直接上代码了#include<stdio.h>#include<strin

新消费降温,良品铺子还能走多远?

如果时间倒退到多年前,杨红春应该不会料到现在良品铺子的境遇。从2006年创立至今,前半段良品铺子经历了品牌升级,从线下发展到平台电商、社交电商,做APP客户端进行全渠道的营销,把一家曾入不敷出的小店,养成年利润过亿的高端零食大公司,似乎每一步都精准地踏在时代的节骨眼上。行业层面,国内零食市场规模也从杨红春刚创业时的数千

Next.js 13 服务器组件和应用目录完整指南

通过关于使用服务器组件和应用程序目录的最完整和最权威的教程,释放Next.js13的全部潜力。目录Next.js13带来了什么?服务器组件(RSC)布局ServerActions服务器操作EnhancedRouter增强型路由器什么是服务器组件?服务器组件与客户端组件定义服务器组件定义客户端组件App应用目录文件结构托

Docker 架构解析:理解 Docker 引擎和容器运行时

🌷🍁博主猫头虎带您GotoNewWorld.✨🍁🦄博客首页——猫头虎的博客🎐🐳《面试题大全专栏》文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺🌊《IDEA开发秘籍专栏》学会IDEA常用操作,工作效率翻倍~💐🌊《100天精通Golang(基础入门篇)》学会Golang语言,畅玩云原生,走遍大

【计算机组成原理】读书笔记第四期:从源文件到可执行文件

目录写在开头从源代码到本地代码源代码本地代码的初级形态(这一节有点不严谨)编译器从目标文件到可执行文件启动和库文件DLL文件及导入库可执行文件的运行机制变量和函数的内存地址程序加载时生成栈和堆结尾写在开头本文继续阅读总结《程序是怎样跑起来的》这本书(作者:矢泽久雄)。前三篇博客介绍了这本书的阅读感受,并分别对第一章CP

如何修复msvcp140.dll文件,msvcp140.dll丢失的解决方法

在使用电脑的过程中,可能会遇到提示“msvcp140.dll丢失”的错误。这通常是由于某些程序或游戏在运行时需要调用msvcp140.dll文件,但由于某种原因(如病毒感染、误删等),该文件被删除或损坏,导致程序无法正常运行。解决方法1.重新安装相关程序当出现msvcp140.dll丢失的错误时,首先尝试重新安装出现问

Haproxy集群与常见的Web集群调度器

文章目录1.Web集群调度器概述1.1Web集群调度器简介1.2调度器类别1.2.1常用软件类1.2.2常用硬件类2.Haproxy软件介绍2.1Haproxy简介2.2支持功能2.3主要特性2.4常用调度算法2.4.1轮询:RR(RoundRobin)2.4.2最小连接数:LC(LeastConnections)2.

MongoDB-1入门介绍

NoSQLNoSQL(NoSQL=NotOnlySQL),意即反SQL运动,指的是非关系型的数据库优点1、对数据库高并发读写。2、对海量数据的高效率存储和访问。3、对数据库的高可扩展性和高可用性。弱点:1、数据库事务一致性需求2、数据库的写实时性和读实时性需求3、对复杂的SQL查询,特别是多表关联查询的需求简介Mong

热文推荐