约瑟夫环问题(带密码)

编号为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;
}

约瑟夫环问题(带密码)相关推荐

  1. 【数据结构与算法】 01 链表 (单链表、双向链表、循环链表、块状链表、头结点、链表反转与排序、约瑟夫环问题)

    一.线性表 1.1 概念与特点 1.2 线性表的存储结构 1.3 常见操作 1.4 应用场景 二.链表 2.1 链表简介 2.2 单向链表(单链表) 2.21 基本概念 2.22 单链表基本操作 2. ...

  2. 约瑟夫环 单向循环链表实现

    约瑟夫环 已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到m的那个人出列:他的下一个人又从1开始报数,数到m的那个人又出列:依此规律重复下去,直到圆桌周围 ...

  3. 这样给面试官解释约瑟夫环问题的几种巧妙解法,面试官满意的笑了

    转载请联系公众号:bigsai 前言 约瑟夫环问题是算法中相当经典的一个问题,其问题理解是相当容易的,并且问题描述有非常多的版本,并且约瑟夫环问题还有很多变形,这篇约瑟夫问题的讲解,一定可以带你理解通 ...

  4. 【Java】单循环链表解决约瑟夫环问题

    问题描述 据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自 ...

  5. C语言约瑟夫报数出圈算法,c语言实现约瑟夫环问题

    (一)基本问题 1.问题描述 设有编号为1,2,-,n的n(n>0)个人围成一个圈,每个人持有一个密码m.从第一个人开始报数,报到m时停止报数,报m的人出圈,再从他的下一个人起重新报数,报到m ...

  6. C语言解决约瑟夫环问题 详细注释

    约瑟夫环算法是: n 个人围成一圈,每个人都有一个互不相同的密码,该密码是一个整数值,选择一个人作为起点,然后顺时针从 1 到 k(k为起点人手中的密码值)数数.数到 k 的人退出圈子,然后从下一个人 ...

  7. 【苦练基本功1】三种方法实现约瑟夫环问题

    1.约瑟夫环问题描述 有n个人围城一圈,按顺序编号,从第一个人开始报数,从1报到m,凡报到m的人退出圈子,然后接着报数,问最后留下来的是原来的第几号的那位? 2.数组实现 用长度为n的数组存储人的编号 ...

  8. 约瑟夫环c语言单链表的解题思路,太透彻了:约瑟夫环的三种解法

    [CSDN 编者按]极大概率出现在面试中的约瑟夫环问题来啦,本文三种方法描述解题思路,这样讲解绝对让面试官眼前一亮. 作者 | bigsai 责编 | 欧阳姝黎 前言 约瑟夫环问题是算法中相当经典的一 ...

  9. c语言循环单链表实现约瑟夫环问题

    题目: 约瑟夫(Joeph)问题的一种描述是:编号为1,2,-,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数).一开始任选一个正整数作为报数上限值max,从第一个人开始按顺时针方向自1开始 ...

最新文章

  1. (一三〇)UITextField的光标操作扩展
  2. 深度学习笔记第二门课 改善深层神经网络 第二周:优化算法
  3. ap java内容_AP 计算机知识点总结
  4. SQL Server插入中文数据出现乱码问题
  5. 理解Linux中断 (3)【转】
  6. 计算机视觉中的人类感知、理解和生成 (ICCV 2019 Workshop)
  7. 菜鸟的MySQL学习笔记(一)
  8. 10-2 使用Channel等待任务结束
  9. java怎么根据编号修改数据类型_Java中怎么根据不同的输入数据类型调用不同的方法呢?...
  10. layui中input、select、date日历的onchange事件无效 解决方法总结
  11. php-5.4 升级到 php7.2
  12. 【运筹学】对偶理论 : 互补松弛定理应用 ( 原问题与对偶问题标准形式 | 已知原问题最优解求对偶问题最优解 | 使用单纯形法求解 | 使用互补松弛定理公式一求解 | 互补松弛定理公式二无效 ) ★★
  13. 不会聊天?不会撩妹?宅男如何走出自闭的循环圈
  14. 谷歌浏览器不能正常显示
  15. 阿里云直播鉴权和直播地址算法
  16. Python——爬虫抓取图片
  17. 啥是数据处理能力?(二)数据处理工具
  18. 谷歌书签同步到gitee
  19. 2020-12-18T16:51:56+08:00 时间转换方法
  20. 人民币衍生品风险不容忽视

热门文章

  1. 执行SQL-MapperProxy.invoke()
  2. 搭建基础架构-QueryRule
  3. IDEA下SVN基本使用
  4. 发布订阅之topics
  5. SpringMVC+Spring+mybatis
  6. Ubuntu安装vscode步骤
  7. 零元学Expression Blend 4 - Chapter 38 看如何使用Clip修出想要的完美曲线(下)
  8. 利用Sqoop将MySQL海量测试数据导入HDFS和HBase
  9. Xilinx下载方式(具体可以参考配置MCS文件时右下角help调出的doc)
  10. 中国人工智能学会通讯——最优传输理论在机器学习中的应用 1.1 最优传输理论与 WGAN 模型...