码迷,mamicode.com
首页 > 编程语言 > 详细

一道约瑟夫算法题的简单设计

时间:2016-10-30 00:32:44      阅读:220      评论:0      收藏:0      [点我收藏+]

标签:但我   准备工作   推出   cout   创建   names   idt   有趣   out   

说约瑟夫问题,网上是有一大堆各种各样的文章,想必也给出了各种各样的代码,但这却不能阻挡我写这篇博文的心啊,要知道我才刚刚开通个博客不写点什么总觉得空虚。。。。

那么就先来讲一下我所要解决的问题:N个人围坐成一圈,从1开始顺序编号;游戏开始,从第一个人开始由1到m的顺序报数,报道m的人退出圈外,问最后留下来那个人原来的序号。

(百度了一下发现,原题目不是推出圈外而是“39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式”。。。)

技术分享

好吧回归正题,我们继续讲这个算法。

在这里我们用c++语言来实现这个算法。网上有人给出了递归算法,那么我这里就讲一种我最开始想到的方法吧。(好吧其实是那个递归的我需要一点时间理解。。。)

首先我们来理清一下思路。假设有10个人,那么我们容易想到用一个数组。所以先得有一个数组。那么怎么样去判断这个人还在不在?我们可以先把数组元素初始化为1,每当一个人出局,就把相应元素设置为0。

然后呢,我们增加一个变量来统计淘汰的人数,一旦到了14人,就是(人数-1),就不用再继续啦。技术分享

现在我们就开始编写c++代码。

首先还是引入头文件什么的,这里说明一下,我们这里就先不采用动态创建数组,我们假设一开始就知道有多少人,报到数字几要出局。因此我们这里定义两个常量(准确地说是文本替换),一个是人数all,一个是报到要出局的数字,定义为out。

#include <iostream>
using namespace std;
#define all 10
#define out 8

显然我们这里设置它人数为10人,报到数字8就要出局。

int people[all];
int k=0,i,j,flag=1;

k是一个从0开始的计次,k%all就是当前正在检验的人的序号(注意,这里说是检验,是因为这个数组元素不一定有报数的资格。),而flag是一个标示,用于判断是否要退出循环。j用于统计被淘汰了多少人,i的话。。。。。似乎很常见,不介绍了。这几个变量我们等下看具体实现的时候会更清楚。

然后对数组进行初始化:

for(i=0;i<all;i++){
        people[i]=1;
    }

然后把i,j置零。

i=0;
j=0;

 

准备工作就完成了,下面开始真正这个算法。

    while(1){
        if(people[k%all]){
            i++;
            if(i==out){
                people[k%all]=0;
                i=0;
                j++;
            }            
        }
     k++;
if(j==all-1){ flag=0; } if(!flag){ break; } }

下面来说说这个代码。

while(1)就是要让他死循环。。

上文提到k,这是从零开始的一个变量,表示当前正在检验第k%n个数组元素。考虑到为什么是k%n,因为考虑到他是一个循环报数的过程。

if(people[k%all])

这是为了看看这个人元素是不是0,是0就没有报数资格了。

如果有的话,那么就i++。

如果什么时候i=out了,就证明这个人要退出圈外。也就是把数组相应元素设置为0。并且j++,记住j是用来记录淘汰人数的。做完这一步的话k要自增,表示要检验下一个。

那么这个循环会不断地跑啊跑。。。。。一直到j=all-1,也就是说,这个人淘汰了之后,场上就只剩下一个人了!!!!我们就要跳出循环了,所以设置flag=0。跳出循环。

但我们还要看看剩下的是哪一个。。。所以还得加个for循环找出剩下的。

for(i=0;i<all;i++){
    if(people[i]){
        cout<<i+1;
    }
}

 

至于他为什么是i+1。。。。因为序号是从1开始标号的。

那么理论上教程就要结束了,但是既然写博客就不能那么简单。。。。。。。

上面的是程序直接输出一个结果,不够生动有趣。

技术分享

为了生动有趣,我还写了个可以动的演示过程。。。。。

代码我会一起打包放在后面。。。。。这里截几张图。。。

技术分享

这是运行的时候

技术分享

 

 瞬间高大上有木有。。。。。。。

好啦那么到这里这篇东西就写完了。。。。。。祝大家学习进步咯。。。。。

附件:约瑟夫算法(其中有两个cpp文件,1.cpp是正常的,flash.cpp是有趣的。。。。)

2016-10-29 

 

一道约瑟夫算法题的简单设计

标签:但我   准备工作   推出   cout   创建   names   idt   有趣   out   

原文地址:http://www.cnblogs.com/xnsy/p/6011986.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!