c语言约瑟夫环问题,C++_详解约瑟夫环问题及其相关的C语言算法实现,约瑟夫环问题 N个人围成一圈 - phpStudy...

详解约瑟夫环问题及其相关的C语言算法实现

约瑟夫环问题

N个人围成一圈顺序编号,从1号开始按1、2、3......顺序报数,报p者退出圈外,其余的人再从1、2、3开始报数,报p的人再退出圈外,以此类推。

请按退出顺序输出每个退出人的原序号

算法思想用数学归纳法递推。

无论是用链表实现还是用数组实现都有一个共同点:要模拟整个游戏过程,不仅程序写起来比较烦,而且时间复杂度高达O(nm),若nm非常大,无法在短时间内计算出结果。我们注意到原问题仅仅是要求出最后的胜利者的序号,而不是要读者模拟整个过程。因此如果要追求效率,就要打破常规,实施一点数学策略。

为了讨论方便,先把问题稍微改变一下,并不影响原意:

问题描述: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)

实现方法

一、循环链表建立一个有N个元素的循环链表,然后从链表头开始遍历并计数,如果基数i == m,则踢出该元素,继续循环,直到当前元素与下一个元素相同时退出循环

#include

#include

#include

typedef struct lnode

{

int pos;

struct lnode *next;

} lnode;

/**

* 构建循环链表&&循环遍历

*/

void create_ring(lnode **root, int loc, int n)

{

lnode *pre, *current, *new;

current = *root;

pre = NULL;

while (current != NULL) {

pre = current;

current = current->next;

}

new = (lnode *)malloc(sizeof(lnode));

new->pos = loc;

new->next = current;

if (pre == NULL) {

*root = new;

} else {

pre->next = new;

}

// 循环链表

if (loc == n) {

new->next = *root;

}

}

/**

* 约瑟夫环

*/

void kickoff_ring(lnode *head, int p)

{

int i;

lnode *pre, *pcur;

pre = pcur = head;

while (pcur->next != pcur) {

for (i = 1; i < p; i ++) {

pre = pcur;

pcur = pcur->next;

}

printf("%d ", pcur->pos);

pre->next = pcur->next;

free(pcur);

pcur = pre->next;

}

printf("%d\n", pcur->pos);

free(pcur);

}

void print_ring(lnode *head)

{

lnode *cur;

cur = head;

while (cur->next != head) {

printf("%d ", cur->pos);

cur = cur->next;

}

printf("%d\n", cur->pos);

}

int main()

{

int i, p, n;

lnode *head;

while (scanf("%d %d", &n, &p) != EOF) {

// 构建循环链表

for (i = 1, head = NULL; i <= n; i ++)

create_ring(&head, i, n);

// 约瑟夫环

if (p != 1)

kickoff_ring(head, p);

else

print_ring(head);

}

return 0;

}

/**************************************************************

Problem: 1188

User: wangzhengyi

Language: C

Result: Accepted

Time:110 ms

Memory:912 kb

****************************************************************/

二、数组模拟思想跟循环链表类似,少了构建循环链表的过程

#include

#include

int main()

{

int i, index, p, n, remain, delete[3001], flag[3001] = {0};

while (scanf("%d %d", &n, &p) != EOF) {

remain = n;

index = 0;

while (remain >= 1) {

for (i = 0; i < n; i ++) {

if (flag[i] == 0) {

// 报数

index ++;

// 报p者退出圈外

if (index == p) {

// 退出圈外

flag[i] = 1;

// 重新报数

index = 0;

delete[remain - 1] = i + 1;

remain --;

}

}

}

}

// 输出每个退出人的序号

for (i = n - 1; i >= 0; i --) {

if (i == 0) {

printf("%d\n", delete[i]);

} else {

printf("%d ", delete[i]);

}

}

}

return 0;

}

三、数学推导

#include

int main(void)

{

int i, n, m, last;

while (scanf("%d", &n) != EOF && n != 0) {

// 接收报数

scanf("%d", &m);

// 约瑟夫环问题

for (i = 2, last = 0; i <= n; i ++) {

last = (last + m) % i;

}

printf("%d\n", last + 1);

}

return 0;

}

相关阅读:

C#基础之数据类型转换

Android 异步获取网络图片并处理导致内存溢出问题解决方法

jquery中取消和绑定hover事件的实现代码

Spring整合websocket整合应用示例(下)

win7系统在word中插入excel公式的方法

JavaScript将数据转换成整数的方法

Android 加密解密字符串详解

Android列表实现(3)_自定义列表适配器思路及实现代码

Linux系统下Git的基本配置和使用示例

jquery map方法使用示例

详解在Java的Struts2框架中配置Action的方法

获取控件大小和设置调整控件的位置XY示例

Win10 10074预览版键盘输入延迟是什么原因如何解决

mysql分表和分区的区别浅析

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

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

相关文章

《从零构建前后分离的web项目》准备 - 前端了解过关了吗?

前端基础架构和硬核介绍 技术栈的选择 首先我们构建前端架构需要对前端生态圈有一切了解&#xff0c;并且最好带有一定的技术前瞻性&#xff0c;好的技术架构可能日后会方便的扩展&#xff0c;减少重构的次数&#xff0c;即使重构也不需要大动干戈&#xff0c;我通常选型技术栈…

联想w540笔记本参数_2020年12月笔记本电脑推荐!联想、惠普、华为笔记本电脑推荐!18款高性价比笔记本电脑推荐!!!...

前言&#xff1a;笔记本电脑&#xff0c;主要分为三种&#xff1a;轻薄本<全能本<游戏本。轻薄本&#xff0c;又称办公笔记本电脑&#xff0c;因为轻薄方便携带&#xff0c;通常用于移动办公使用。全能本&#xff0c;就是把轻薄本的集显变成了小独显&#xff0c;增加了独…

【BZOJ 1098】办公楼(补图连通块个数,Bfs)

补图连通块个数这大概是一个套路吧&#xff0c;我之前没有见到过&#xff0c;想了好久都没有想出来QaQ 事实上这个做法本身就是一个朴素算法&#xff0c;但进行巧妙的实现&#xff0c;就可以分析出它的上界不会超过 $O(n m)$。 接下来介绍一下这个技巧&#xff1a; 很显然一个…

Spring MVC:资源

我从博客读者那里收到的最常见的问题之一是如何在Spring MVC的应用程序中使用CSS和javascript文件。 因此&#xff0c;这是撰写有关Spring MVC中资源使用情况的文章的好机会。 通常&#xff0c;我将使用基于Java的配置方法。 如今&#xff0c;很难想象没有CSS和JavaScript文件…

map

头文件 首先要引入头文件 #include <map> . 并使用命名空间 using namespace std; 1、插入元素 用pair 或者 make_pair 均可&#xff0c;map键值不能重复。 map1.insert(pair<int,string>(123,"aaaaa")); //pair map1.insert(make_pair<int,string&…

c语言读文件空格间隔,c语言文件流实现按单个词读取(以空格、分号等作间隔)...

c语言文件流实现按词读取(以空格、分号等作间隔)1.基本描述在之前的作业中&#xff0c;认真编写代码&#xff0c;从中发现不少知识积累上的欠缺。编程中使用到的c语言文件读取&#xff0c;要求是按照获取到一个完整的词&#xff0c;并对其进行处理。写有java或c语言源程序的.tx…

山东专升本access知识点_全国各省份每年的专升本考试大纲啥时候公布?考纲公布之前你该做什么?...

?星标/置顶专升本招考下一个上岸的就是你最近小编在专升本招考后台收到很多同学的留言&#xff0c;大多同学都是看到好多省都公布了专升本考试政策和大纲&#xff0c;却迟迟不见自己所在的省份出&#xff0c;于是火急火燎地找到小编来问&#xff1a;XX省的考试大纲到底啥时候出…

2018091-2 博客作业

此作业的要求参见https://edu.cnblogs.com/campus/nenu/2018fall/homework/2101 1.建博客 在 cnblogs.com (博客园)建账号。博客地址&#xff1a;https://www.cnblogs.com/LY0503/ 2. 博客作业 &#xff08;1&#xff09;回想一下你曾经对计算机专业的畅想 当初你是如何做出选择…

观点|蚂蚁金服玉伯:我们是如何从前端技术进化到体验科技的?

小蚂蚁说&#xff1a;王保平&#xff0c;花名玉伯。熟悉前端和SeaJS的人一定对这个名字不陌生。作为前端领域的一枚大大大牛&#xff0c;他现在担任蚂蚁金服体验技术部负责人。本文&#xff0c;他分享了他从前端一路进阶升级到体验科技的个人思考&#xff0c;并详细介绍了体验科…

excel 电阻并联计算_电路分析基础(5)-关于电阻,有些话我还是要说一说

电阻定义&#xff1a;导体对电流的阻碍作用就叫该导体的电阻。不同的导体&#xff0c;电阻一般不同&#xff0c;电阻是导体本身的一种性质。定义式如下&#xff1a;因此&#xff0c;我们应该清楚了欧姆定律的本质到底是什么&#xff0c;为啥电阻跟电压和电流没有关系&#xff0…

针对新手的Java EE7和Maven项目–第2部分–为我们的应用程序定义一场简单的战争...

从第一部分恢复 第1部分 我们刚刚定义了父 pom。 一种特殊的pom类型&#xff0c;它最终定义了我们的应用程序将要使用的库。 它还配置了所有用于打包我们应用程序每个模块的Maven工具。 您可以在此处 签出 -1部分示例代码。 因此&#xff0c;到目前为止&#xff0c;在将要开发…

postman实现从response headers中获取cookie,并将其设置为环境变量

1.最近在学习postman的使用方法,为了保证后续模块操作&#xff0c;必须在登录时获取的session值&#xff0c;并将其设置为环境变量&#xff0c;session的位置处于response headers里面返回的set-cookie参数&#xff0c;并且将set-cookie中的session通过split方法截取出来. 写法…

c语言如何在文件中间插入数据,急求如何将下列C语言程序数据存储到文件中?...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼求如何改动才能将下列程序的存储输入或输出数据(或两者一起)到指定的文件(或运行时直接创立一个文件)如Arrangement中。#include int n0;int rest[7][7]; //全局声明,以供全局调用int main(){void perm(int list[],int ,int );int …

010 pandas的DataFrame

一&#xff1a;创建 1.通过二维数组进行创建 2.取值 取列,取位置的值 3.切片取值 这个和上面的有些不同&#xff0c;这里先取行&#xff0c;再取列 4.设定列索引 这里使用的行索引与上面不同。 5.通过字典的方式创建 6.索引 包含行索引&#xff0c;与列索引 7.修改列索引 转载于…

unity烘培单个物体_Unity可编程渲染管线(SRP)教程:二、自定义着色器

本文翻译自Catlike Coding&#xff0c;原作者&#xff1a;Jasper Flick。本文经原作者授权&#xff0c;转载请说明出处。原文链接在下&#xff1a;https://catlikecoding.com/unity/tutorials/scriptable-render-pipeline/custom-shaders/​catlikecoding.com本章内容如下&…

线程跳动

总览 线程jiggler是一个简单的测试框架&#xff0c;用于执行代码以查找线程问题。 它通过在运行时修改字节码类的类来工作&#xff0c;以在指令之间插入Thread.yield&#xff08;&#xff09;调用&#xff0c;从而“微动”线程。 这极大地增加了发现线程问题的可能性&#xff0…

一套比较完整的前端技术选型,需要规整哪些东西,你知道不?

1. 背景及现状 随着前端开发复杂度的日益增加&#xff0c;各种优秀的组件框架也遍地开花。同时&#xff0c;我们面临业务规模的快速发展和工程师团队的不断扩张&#xff0c;如何解决资源整合、模块开发、项目部署、性能优化等问题势在必行。 2. 目标 根据背景和现状的分析&a…

asp.net core2.0里的Nlog

Microsoft.Extensions.Logging&#xff0c;到了Version2.0.0.0&#xff0c;没了AddNlog() ? ——我找不到输出的日志&#xff01; 。。。。。经过一番百度 step1:添加个Provider 这样&#xff0c;在Startup里Configure实现一个ILoger 如果在controller里使用&#xff1f;——…

android 回退函数,详解React Native监听Android回退按键与程序化退出应用

详解React Native监听Android回退按键与程序化退出应用发布时间&#xff1a;2020-09-29 09:25:52来源&#xff1a;脚本之家阅读&#xff1a;137作者&#xff1a;lqh详解React Native监听Android回退按键与程序化退出应用前言我们知道Android回退按键&#xff0c;会控制页面返回…

ajax 全局拦载处理,可加密、过滤、筛选、sql防注入处理

//此方法放在公用的js里面即可。如此&#xff1a;所有的ajax请求都会通过此 $.ajaxSetup({ contentType: "application/x-www-form-urlencoded;charsetutf-8", beforeSend: function() { //发送前执行的函数 try { /** * 当 processData: false,此时后台接收的值都会…