加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

约瑟夫问题 圆圈报数

(2016-01-06 11:21:17)
标签:

c学习

分类: c 程序进阶

约瑟夫问题:N个人围成一圈,从第一个人开始报数,数到M的人出圈;再由下一个人开始报数,数到M的人出圈;…输出依次出圈的人的编号。NM由键盘输入。

【分析】

1)由于对于每个人只有出圈和没有圈两种状态,因此可以用布尔型标志数组存储游戏过程中每个人的状态。不妨用true表示出圈,false 表示没有出圈。

    2)开始的时候,给标志数组赋初值为false,即全部在圈内。

3)模拟报数游戏的过程,直到所有的人出圈为止。

         3)模拟报数游戏的过程,直到所有的人出圈为止。

 程序如下:

  #include

  using namespace std;

  int n,m,s,f,t;

  bool a[101];           //根据题意开出数组大小

  int main()

       {

            cin>>n>>m;          //n人,报到m出圈

            cout<<endl;

            for (t=1;t<=n;++t) a[t]=false;    //等同于memset(a,0,sizeof(a)),要调用cstring

            f=0;  t=0;  s=0;       //刚开始所有变量默认值也是0,或者用f=t=s=0;

           do

           {

                 ++t;                //逐个枚举圈中的所有位置

              if (t==n+1) t=1;     //数组模拟环状,最后一个与第一个相连

              if (a[t]==false) ++s;       //t个位置上有人则报数

              if (s==m)              //当前报的数是m

              {

         s=0;        //计数器清零

                      cout<<t<<" "; //输出出圈人的编号

                      a[t]=true;        //此处的人已出圈,设置为空

                      f++;      //出圈的人数增加一个

               }

            } while(f!=n);        //直到所有的人都出圈为止

         return 0;

  }

 

  运行结果:

  输入: 5

  输出: 5 2 8 7 1 4 6 3

  这是一个在算法设计上很有名气的经典约瑟夫(Josephu)问题,它有很多变例。如猴子选大王、持密码报数、狐狸追兔子等。

 

 

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有