头脑风暴之约瑟夫环问题

一 问题的引入

约瑟夫问题的源头完全可以命名为“自杀游戏”。本着和谐友爱和追求本质的目的,可以把问题描述如下:

  • 现有n个人围成一桌坐下,编号从1到n,从编号为1的人开始报数。
  • 报数也从1开始,报到m人离席,从离席者的下一位在座成员开始,继续从1开始报数。
  • 复现这个过程(各成员的离席次序),或者求最后一个在座的成员编号。

二 思路的讲解

1. 想必我们看到这个游戏场景,再结合链表相关的知识,我们也就大概有了一个方向了吧~~~

没错,解决约瑟夫问题的关键就是创建一个带环链表

 2.当我们链表创建好之后,就是考虑如何讲单链表转换成带头循环链表

是滴,就是将我们的链表的尾结点指向我们的头节点即可

ptail->next = phead;

 对应代码如下:

ListNode* CreatList(int x)//链表创建
{ListNode* phead = ListBuyNode(1);//注意是从数据1开始为每一个人创建结点ListNode* ptail = phead;//注意当链表只有一个数据时,头节点也是尾结点//来到这里说明头节点已经创建好,下面就需要进行尾插即可,尾插之前需找到前面的结点for (int i = 2; i <= x; i++){ListNode* node = ListBuyNode(i);ptail->next = node;ptail = ptail->next;//尾结点时刻更新}//以上只是单链表创建好了,下面需把他变成单向循环链表ptail->next = phead;return ptail;//返回尾结点即可,有了尾结点可以直接找到头节点,若是返回头节点,需要遍历才可以找到尾结点}

3.以上我们把前期准备工作已经做好了,接下来我们开始约瑟夫游戏

其实就是一个删除结点的问题

注意我们这里不能直接删除结点

1.)删除结点之前我们需要先找到这个结点的前一个结点,也就是pre这个结点

2.)其次就是找到这个结点的后一个结点,即pcur->next;

3.)最最最重要的是,我们在删除这个结点之后,不要忘了让下一个人重新报数

草图如下:

 代码如下:

 接下来重复以上操作即可,也就是对应代码里面的循环,具体详见代码:

    while (pcur->next != pcur){if (count == m){//报到为m 的人直接删除就Okpre->next = pcur->next;free(pcur);//此时pcur是个野指针pcur = pre->next;count = 1;//删除结点后,别忘了count 是从1重新开始报数}else{pre = pcur;//pcur移动之前,需让pre 来保存pcur位置,pcur = pcur->next;count++;//注意别忘了要报数}}

相信各位对以上的分析应该有了自己的理解了吧~~~

 

对于IO答题方式:完整代码如下:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<assert.h>
#include<malloc.h>int yef(int x, int y);
typedef struct ListNode
{int val;//数据域struct ListNode* next;//指针域
}ListNode;//重命名
ListNode* ListBuyNode(int x)//创建结点
{ListNode* node = (ListNode*)malloc(sizeof(ListNode));if (node == NULL)//会存在开辟失败{perror("malloc fail\n");return 5;}//空间开辟成功node->val = x;node->next = NULL;return node;
}
ListNode* CreatList(int x)//链表创建
{ListNode* phead = ListBuyNode(1);//注意是从数据1开始为每一个人创建结点ListNode* ptail = phead;//注意当链表只有一个数据时,头节点也是尾结点//来到这里说明头节点已经创建好,下面就需要进行尾插即可,尾插之前需找到前面的结点for (int i = 2; i <= x; i++){ListNode* node = ListBuyNode(i);ptail->next = node;ptail = ptail->next;//尾结点时刻更新}//以上只是单链表创建好了,下面需把他变成单向循环链表ptail->next = phead;return ptail;//返回尾结点即可,有了尾结点可以直接找到头节点,若是返回头节点,需要遍历才可以找到尾结点}
int ysf(int n, int m) {ListNode* ptail = CreatList(n);//为1~n个人创建单循环链表,注意链表创建返回的就是尾结点//开始游戏,涉及到删除结点,注意不能直接删除,删除前需要先找到对应的前一个结点和后一个结点ListNode* pcur = ptail->next;//游戏是从第一个人开始的ListNode* pre = ptail;//当前节点的前一个结点int count = 1;//就是一个报数器,注意是从1开始的而不是0开始的,因为游戏是从第一个人开始while (pcur->next != pcur){if (count == m){//报到为m 的人直接删除就Okpre->next = pcur->next;free(pcur);//此时pcur是个野指针pcur = pre->next;count = 1;//删除结点后,别忘了count 是从1重新开始报数}else{pre = pcur;//pcur移动之前,需让pre 来保存pcur位置,pcur = pcur->next;count++;//注意别忘了要报数}}//此时只剩一个结点return pcur->val;
}
int main()
{int ret =  ysf(43,9001);printf("%d", ret);return 0;
}

对于OJ的答题方式,完整代码如下

//解答思路 首先创建一个带头单向循环链表  其次删除这个链表的结点,注意不能直接删除,要找到删除此节点的前一个和后一个结点typedef struct ListNode ListNode;//重命名ListNode* ListBuyNode(int x)//创建结点{ListNode* node = (ListNode*)malloc(sizeof(ListNode));if(node == NULL)//会存在开辟失败{perror("malloc fail\n");}//空间开辟成功node->val = x;node->next = NULL;return node;}ListNode* CreatList(int x)//链表创建{ListNode* phead = ListBuyNode(1);//注意是从数据1开始为每一个人创建结点ListNode* ptail = phead;//注意当链表只有一个数据时,头节点也是尾结点//来到这里说明头节点已经创建好,下面就需要进行尾插即可,尾插之前需找到前面的结点for(int i = 2;i <= x;i++){ListNode* node = ListBuyNode(i);ptail->next = node;ptail = ptail->next;//尾结点时刻更新}//以上只是单链表创建好了,下面需把他变成单向循环链表ptail->next = phead;return ptail;//返回尾结点即可,有了尾结点可以直接找到头节点,若是返回头节点,需要遍历才可以找到尾结点}
int ysf(int n, int m ) {ListNode* pre = CreatList(n);//为1~n个人创建单循环链表,注意链表创建返回的就是尾结点//开始游戏,涉及到删除结点,注意不能直接删除,删除前需要先找到对应的前一个结点和后一个结点ListNode* pcur = pre->next;//游戏是从第一个人开始的int count = 1;//就是一个报数器,注意是从1开始的而不是0开始的,因为游戏是从第一个人开始while(pcur->next != pcur){if(count == m){//报到为m 的人直接删除就Okpre->next  = pcur->next;free(pcur);//此时pcur是个野指针pcur = pre->next;count = 1;//删除结点后,别忘了count 是从1重新开始报数}else {pre = pcur;//pcur移动之前,需让pre 来保存pcur位置,pcur = pcur->next;count++;//注意别忘了要报数}}//此时只剩一个结点return pcur->val;}

 各位大佬都已经来这里了,若是觉得还不错,咱点个赞,互关一下呗,蟹蟹大家了,小生有礼了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/145467.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java面试——RPC协议

涉及到分布式方面知识的话&#xff0c;RPC协议是逃不开的&#xff0c;所以在此记录一下RPC协议。 什么是RPC协议 RPC协议&#xff08;Remote Procedure Call&#xff09;远程过程调用&#xff0c;简单的来说&#xff1a;RPC协议是一种通过网络从远程计算机程序获取服务的协议…

cocos creator 小游戏允许他人访问本地项目

需求背景&#xff1a; 发版成微信小游戏前&#xff0c;需要策划介入体验。不上传微信体验版本 实现&#xff1a; 1.发布平台选择web桌面端 2.构建完成后点击运行从浏览器上获取本地的运行地址 3.winR ——》 cmd 控制台 输入 ipconfig 找到IPv4地址&#xff0c;替换本地部分 …

3BHE003855R0001 UNS2882A 用于嵌入式/工业用途的人工智能盒

3BHE003855R0001 UNS2882A 用于嵌入式/工业用途的人工智能盒. 无风扇iBOX 1200系列包括型号iBOX-1265 UE/iBOX-1245 UE/iBOX-1215 UE&#xff0c;由第12代英特尔酷睿i7/i5/i3处理器(Alder Lake-P)提供动力&#xff0c;通过英特尔Iris Xe显卡和两个DDR4 3200MHz SO-DIMM提供高达…

Windows环境如何使用Zblog+cpoalr搭建个人网站并远程访问?

文章目录 1. 前言2. Z-blog网站搭建2.1 XAMPP环境设置2.2 Z-blog安装2.3 Z-blog网页测试2.4 Cpolar安装和注册 3. 本地网页发布3.1. Cpolar云端设置3.2 Cpolar本地设置 4. 公网访问测试5. 结语 1. 前言 想要成为一个合格的技术宅或程序员&#xff0c;自己搭建网站制作网页是绕…

设计模式:模板模式(C#、JAVA、JavaScript、C++、Python、Go、PHP)

简介&#xff1a; 模板模式&#xff0c;它是一种行为型设计模式&#xff0c;它定义了一个操作中的算法的框架&#xff0c;将一些步骤延迟到子类中实现&#xff0c;使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 通俗地说&#xff0c;模板模式就是将某一行…

【ARM裸机】ARM入门

1.ARM成长史 2.ARM的商业模式和生态系统 ARM只设计CPU&#xff0c;但是不生产CPU 3.为什么使用三星&#xff1a;S5PV210 4.各种版本号 0. ARM和Cortex Cortex就是ARM公司一个系列处理器的名称。比如英特尔旗下处理器有酷睿&#xff0c;奔腾&#xff0c;赛扬。ARM在最初的处理器…

程序包org.apache.ibatis.mapping不存在 符号找不到

找不到符号 符号: 类 Cursor和程序包org.apache.ibatis.mapping不存在 在idea中没有错误&#xff0c;但是在linux编辑时报了这两个错误&#xff0c;之前有遇见过符号找不到的问题&#xff0c; 当时的问题是编译的import xxx.xxx.xxx.* 识别不成功过&#xff0c;将*改为…

网络协议--ICMP:Internet控制报文协议

6.1 引言 ICMP经常被认为是IP层的一个组成部分。它传递差错报文以及其他需要注意的信息。ICMP报文通常被IP层或更高层协议&#xff08;TCP或UDP&#xff09;使用。一些ICMP报文把差错报文返回给用户进程。 ICMP报文是在IP数据报内部被传输的&#xff0c;如图6-1所示。 ICMP…

卷积神经网络CNN学习笔记-MaxPool2D函数解析

目录 1.函数签名:2.学习中的疑问3.代码 1.函数签名: torch.nn.MaxPool2d(kernel_size, strideNone, padding0, dilation1, return_indicesFalse, ceil_modeFalse) 2.学习中的疑问 Q:使用MaxPool2D池化时,当卷积核移动到某位置,该卷积核覆盖区域超过了输入尺寸时,MaxPool2D会…

为什么学完了 C#觉得自己什么都干不了?

为什么学完了 C#觉得自己什么都干不了&#xff1f; 俺一向的观点&#xff1a;&#xff08;1&#xff09;学跟干是两码事。学&#xff0c;你要往外掏钱或时间或两个都得掏。干&#xff0c;是你从别人兜里掏钱。&#xff08;2&#xff09;如果没有干的需求&#xff0c;那么可以啥…

小白也会的校园网宽带拨号自动重连设置

开始菜单搜索“任务计划程序”&#xff1a;我这个开始菜单和你们的不太一样&#xff0c;用了StartAllBack设置的&#xff0c;总之能找到这个程序就行了 提示&#xff1a;可以按下“Win R”&#xff0c;打开“运行”&#xff0c;输入taskschd.msc来打开任务计划程序 点击“任务…

灰度发布专题---1、灰度发布的意义和方案

线上项目灰度发布的重大意义 支付宝等软件相信大家一定不陌生&#xff0c;支付宝经历了十多年&#xff0c;从未停止更新过&#xff0c;app从最初简单设计到现在的扁平化设计&#xff0c;一直在更新&#xff0c;但奇怪的是它从未停过服务&#xff0c;而且越用越顺畅。不停服务就…