当前位置: 首页 > news >正文

C++ - 8月31日 - 约瑟夫环问题

问题描述:

约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3,...n分别表示)围坐在一张圆桌周围,从编号为k的人开始报数,数到m的那个人出圈,他的下一个人又从1开始报数,数到m的那个人又出圈;按照这个规律一直重复下去,最后一个出局的人为游戏的最终胜利者。

举例分析:

例如:我们现在假设有10个人围成一圈进行约瑟夫环游戏,每个人的编号为0-9,现在规定数到3的人出圈,我们在画板上分析此过程:

初始状态为:

我们从编号为0的人开始报数,编号0报数为1, 编号1报数为2,编号2报数为3,现在编号为2的人出局:

现在我们从编号为3的人开始重新报数,编号3报数为1,编号4报数为2,编号5报数为3,编号5出局:

现在从编号为6的人开始报数,编号6的人报数为1 ,编号7的人报数为2,编号8的人报数为3,编号8的人出局:

 现在从编号为9的人开始报数,编号9的人报数为1 ,编号0的人报数为2,编号1的人报数为3,编号1的人出局:

现在本来应该从编号1后面的那个人开始报数,但是编号2的人在第一轮已经出局,所以我们直接跳过编号为2的人,从编号为3的人开始报数,编号3的人报数为1 ,编号4的人报数为2,将第二轮出局的编号5跳过,编号6的人报数为3,编号6的人出局: 

现在从编号为7的人开始报数,编号7的人报数为1 ,跳过已经出局的编号8,编号9的人报数为2,编号0的人报数为3,编号0的人出局: 

跳过已经出局的编号1和编号2, 现在从编号为3的人开始重新报数,编号3报数为1,编号4报数为2,跳过已经出局的编号5和编号6,编号7报数为3,编号7出局:

跳过已经出局的编号8, 从编号9开始报数,编号9报数为1,跳过已经出局的编号0、1、2, 编号3报数为2,编号4报数为3,现在编号为4的人出局:

跳过已经出局的编号5、6、7、8,从编号9开始报数,编号9报数为1,跳过出局的编号0、1、2,编号3报数为2,跳过出局的编号4、5、6、7、8,编号9报数为3,编号9出局,此时约瑟夫环中只剩下编号为3的成员,所以最终的胜利者是编号为3的人:

所以最终出局人编号的顺序为: 2,5,8,1,6,0,7,4,9,3,最后一个出局的人为最终的胜利者

约瑟夫环游戏的过程我们已经基本清楚,我们将思路代码化。

代码实现: 

方法一:数组

//利用数组来解决约瑟夫环
#include<stdio.h>
#include<iostream>
using namespace std;
int arr[100] = {0};//定义一个长度为100的数组且将数组内的元素全部初始化为0,0也表示一个人还在环中
int main()
{
    int n = 0,m = 0;//n表示总共的人数,m表示数到第m个人的时候出局
    int count = 0;//count用作记录出局人数的计数器
    int i = 0,k = 0;//定义两个下标,i用来表示目前报数的编号,k用来记录编号1到编号m的依次报数
    cin >> n >> m;//输入约瑟夫环内的总人数和需要出局的人的编号
    while(count != n){//循环跳出的条件为全部人数全部出局
        i++;//从第一个人往后走
        if(i > n){//如果超过总人数,重新从第一个人开始报数
            i = 1;
        }
        if(arr[i] == 0){//这个人还在环中的话
            k++;//报数操作,从1开始,k在下面归0
            if(k == m){//如果报数到了第m个数字
                arr[i] = 1;//重新将当前这个位置设置为1
                count++;//出局人数加1
                cout << i-1 << " ";//输出当前元素(下标形式)
                k = 0;//对k进行清空。重新从编号1开始报数
            }
        }
    }
    return 0;
}

我们利用程序对上面分析的过程以及结果进行验证:

如图, 我输入总人数为10,数到第3人时出局,出局顺序为:2,5,8,1,6,0,7,4,9,3,与上面分析的结果一样,结果正确。

相关文章:

  • C++ 模板泛型编程
  • Retrofit原理解析(二)
  • 数据结构与算法 -- 子序列问题
  • python中namedtuple函数用法详解
  • C++设计模式---模板方法模式
  • 数据结构和算法——绪论
  • 最小生成树算法的相关变形题
  • Android中常用的几种容器视图的使用
  • 随手记面试录
  • VMware软件下载安装以及在VMware中安装Centos-stream
  • JCL入门教程
  • 5.6如何寻找最长回文子串
  • tkinter-event事件
  • Windows10环境gradle安装与配置
  • DELMIA弧焊虚拟仿真:带变位机的机器人弧焊焊接程序自动生成方法
  • -------------------- 第二讲-------- 第一节------在此给出链表的基本操作
  • Angular Elements 及其运作原理
  • Flannel解读
  • JavaScript实现分页效果
  • MySQL主从复制读写分离及奇怪的问题
  • react-native 安卓真机环境搭建
  • seaborn 安装成功 + ImportError: DLL load failed: 找不到指定的模块 问题解决
  • 技术发展面试
  • 京东美团研发面经
  • 扫描识别控件Dynamic Web TWAIN v12.2发布,改进SSL证书
  • 无服务器化是企业 IT 架构的未来吗?
  • 小程序button引导用户授权
  • 继 XDL 之后,阿里妈妈开源大规模分布式图表征学习框架 Euler ...
  • ​马来语翻译中文去哪比较好?
  • #git 撤消对文件的更改
  • (175)FPGA门控时钟技术
  • (2020)Java后端开发----(面试题和笔试题)
  • (pt可视化)利用torch的make_grid进行张量可视化
  • (二)Eureka服务搭建,服务注册,服务发现
  • (二)换源+apt-get基础配置+搜狗拼音
  • (附程序)AD采集中的10种经典软件滤波程序优缺点分析
  • (附源码)基于ssm的模具配件账单管理系统 毕业设计 081848
  • (六)库存超卖案例实战——使用mysql分布式锁解决“超卖”问题
  • (一) storm的集群安装与配置
  • (一)RocketMQ初步认识
  • (转)eclipse内存溢出设置 -Xms212m -Xmx804m -XX:PermSize=250M -XX:MaxPermSize=356m
  • .bat批处理(六):替换字符串中匹配的子串
  • .NET 反射的使用
  • .Net调用Java编写的WebServices返回值为Null的解决方法(SoapUI工具测试有返回值)
  • .net图片验证码生成、点击刷新及验证输入是否正确
  • @Autowired标签与 @Resource标签 的区别
  • [Angular 基础] - 表单:响应式表单
  • [AX]AX2012 R2 出差申请和支出报告
  • [AX]AX2012开发新特性-禁止表或者表字段
  • [C++参考]拷贝构造函数的参数必须是引用类型
  • [Electron]ipcMain.on和ipcMain.handle的区别
  • [GN] DP学习笔记板子
  • [Java]快速入门二叉树,手撕相关面试题
  • [JavaEE]线程的状态与安全
  • [Kubernetes]4. 借助腾讯云TKE快速创建Pod、Deployment、Service部署k8s项目