约瑟夫环问题(带密码)
约瑟夫环问题(带密码)
编号为1,2,…,n的n个人按顺时针方向围坐一圈,每个人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m 值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直到所有人全部出列为止。例如,n=7,7个人的密码依次为:3,1,7,2,4,8,4,m的初值取6,则正确的出列顺序应为6,1,4,7,2,3,5
分析
约瑟夫环的大小是变化的,因此相应的结点也是变化的,使用链式存储结构可以动态的生成其中的结点,出列操作也非常简单。用单向循环链表模拟其出列顺序比较合适
解决
用结构指针描述每个人
struct Joseph {//约瑟夫环中某个人的序号int number;//约瑟夫环中某个人的密码int password;//约瑟夫环的下一个节点struct Joseph *next;
};
初始化约瑟夫环
Node *init(int n, int array[]) {int i = 1;//链表头结点Node *head;//链表当前节点Node *current;//链表下一个节点Node *next;current = static_cast<Node *>(malloc(sizeof(Node)));current->number = i;current->password = array[i - 1];head = current;for (i = 2; i <= n; ++i) {next = static_cast<Node *>(malloc(sizeof(Node)));next->number = i;next->password = array[i - 1];//连接链表与新创建的节点current->next = next;current = next;}//尾节点连接到头结点,形成循环链表current->next = head;return head;
}
报数出列
void function(Node *head, int len, int password) {//前一个节点Node *pre;//后一个节点Node *next;//要删除的节点Node *temp;//初始化next = head;for (int i = 1; i < len; ++i) {pre = next->next;next = next->next;}//遍历所有人for (int i = 1; i <= len; ++i) {//先将指针移动到出列的前一个for (int j = 1; j < password; ++j) {pre = pre->next;}//保存要删除的节点temp = pre->next;//下一个节点next = temp->next;//修改密码password = temp->password;//输出出列序号cout << temp->number << endl;//连接链表,去除中间节点pre->next = next;//释放中间节点free(temp);}
}
完整代码
#include <iostream>using namespace std;struct Joseph {//约瑟夫环中某个人的序号int number;//约瑟夫环中某个人的密码int password;//约瑟夫环的下一个节点struct Joseph *next;
};typedef Joseph Node;/*** 初始化约瑟夫环* @param n 成员数目* @param array 每个人的密码* @return 头结点*/
Node *init(int n, int array[]) {int i = 1;//链表头结点Node *head;//链表当前节点Node *current;//链表下一个节点Node *next;current = static_cast<Node *>(malloc(sizeof(Node)));current->number = i;current->password = array[i - 1];head = current;for (i = 2; i <= n; ++i) {next = static_cast<Node *>(malloc(sizeof(Node)));next->number = i;next->password = array[i - 1];//连接链表与新创建的节点current->next = next;current = next;}//尾节点连接到头结点,形成循环链表current->next = head;return head;
}/*** 遍历约瑟夫环,报数出列* @param head 头结点* @param len 约瑟夫环长度* @param password 初始密码*/
void function(Node *head, int len, int password) {//前一个节点Node *pre;//后一个节点Node *next;//要删除的节点Node *temp;//初始化next = head;for (int i = 1; i < len; ++i) {pre = next->next;next = next->next;}//遍历所有人for (int i = 1; i <= len; ++i) {//先将指针移动到出列的前一个for (int j = 1; j < password; ++j) {pre = pre->next;}//保存要删除的节点temp = pre->next;//下一个节点next = temp->next;//修改密码password = temp->password;//输出出列序号cout << temp->number << endl;//连接链表,去除中间节点pre->next = next;//释放中间节点free(temp);}
}int main() {//环的长度int len;cout << "输入约瑟夫环的长度:";cin >> len;int array[len];cout << "请输入m的初始值 m:";int m;cin >> m;cout << "请输入每个人的密码: " << endl;for (int i = 0; i < len; ++i) {cin >> array[i];}
// int len = 7;
// int array[] = {3, 1, 7, 2, 4, 8, 4};
// int m = 6;//创建约瑟夫环Node *head = init(len, array);function(head, len, m);return 0;
}
约瑟夫环问题(带密码)相关推荐
- 【数据结构与算法】 01 链表 (单链表、双向链表、循环链表、块状链表、头结点、链表反转与排序、约瑟夫环问题)
一.线性表 1.1 概念与特点 1.2 线性表的存储结构 1.3 常见操作 1.4 应用场景 二.链表 2.1 链表简介 2.2 单向链表(单链表) 2.21 基本概念 2.22 单链表基本操作 2. ...
- 约瑟夫环 单向循环链表实现
约瑟夫环 已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到m的那个人出列:他的下一个人又从1开始报数,数到m的那个人又出列:依此规律重复下去,直到圆桌周围 ...
- 这样给面试官解释约瑟夫环问题的几种巧妙解法,面试官满意的笑了
转载请联系公众号:bigsai 前言 约瑟夫环问题是算法中相当经典的一个问题,其问题理解是相当容易的,并且问题描述有非常多的版本,并且约瑟夫环问题还有很多变形,这篇约瑟夫问题的讲解,一定可以带你理解通 ...
- 【Java】单循环链表解决约瑟夫环问题
问题描述 据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自 ...
- C语言约瑟夫报数出圈算法,c语言实现约瑟夫环问题
(一)基本问题 1.问题描述 设有编号为1,2,-,n的n(n>0)个人围成一个圈,每个人持有一个密码m.从第一个人开始报数,报到m时停止报数,报m的人出圈,再从他的下一个人起重新报数,报到m ...
- C语言解决约瑟夫环问题 详细注释
约瑟夫环算法是: n 个人围成一圈,每个人都有一个互不相同的密码,该密码是一个整数值,选择一个人作为起点,然后顺时针从 1 到 k(k为起点人手中的密码值)数数.数到 k 的人退出圈子,然后从下一个人 ...
- 【苦练基本功1】三种方法实现约瑟夫环问题
1.约瑟夫环问题描述 有n个人围城一圈,按顺序编号,从第一个人开始报数,从1报到m,凡报到m的人退出圈子,然后接着报数,问最后留下来的是原来的第几号的那位? 2.数组实现 用长度为n的数组存储人的编号 ...
- 约瑟夫环c语言单链表的解题思路,太透彻了:约瑟夫环的三种解法
[CSDN 编者按]极大概率出现在面试中的约瑟夫环问题来啦,本文三种方法描述解题思路,这样讲解绝对让面试官眼前一亮. 作者 | bigsai 责编 | 欧阳姝黎 前言 约瑟夫环问题是算法中相当经典的一 ...
- c语言循环单链表实现约瑟夫环问题
题目: 约瑟夫(Joeph)问题的一种描述是:编号为1,2,-,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数).一开始任选一个正整数作为报数上限值max,从第一个人开始按顺时针方向自1开始 ...
最新文章
- (一三〇)UITextField的光标操作扩展
- 深度学习笔记第二门课 改善深层神经网络 第二周:优化算法
- ap java内容_AP 计算机知识点总结
- SQL Server插入中文数据出现乱码问题
- 理解Linux中断 (3)【转】
- 计算机视觉中的人类感知、理解和生成 (ICCV 2019 Workshop)
- 菜鸟的MySQL学习笔记(一)
- 10-2 使用Channel等待任务结束
- java怎么根据编号修改数据类型_Java中怎么根据不同的输入数据类型调用不同的方法呢?...
- layui中input、select、date日历的onchange事件无效 解决方法总结
- php-5.4 升级到 php7.2
- 【运筹学】对偶理论 : 互补松弛定理应用 ( 原问题与对偶问题标准形式 | 已知原问题最优解求对偶问题最优解 | 使用单纯形法求解 | 使用互补松弛定理公式一求解 | 互补松弛定理公式二无效 ) ★★
- 不会聊天?不会撩妹?宅男如何走出自闭的循环圈
- 谷歌浏览器不能正常显示
- 阿里云直播鉴权和直播地址算法
- Python——爬虫抓取图片
- 啥是数据处理能力?(二)数据处理工具
- 谷歌书签同步到gitee
- 2020-12-18T16:51:56+08:00 时间转换方法
- 人民币衍生品风险不容忽视
热门文章
- 执行SQL-MapperProxy.invoke()
- 搭建基础架构-QueryRule
- IDEA下SVN基本使用
- 发布订阅之topics
- SpringMVC+Spring+mybatis
- Ubuntu安装vscode步骤
- 零元学Expression Blend 4 - Chapter 38 看如何使用Clip修出想要的完美曲线(下)
- 利用Sqoop将MySQL海量测试数据导入HDFS和HBase
- Xilinx下载方式(具体可以参考配置MCS文件时右下角help调出的doc)
- 中国人工智能学会通讯——最优传输理论在机器学习中的应用 1.1 最优传输理论与 WGAN 模型...