回 帖 发 新 帖 刷新版面

主题:约瑟夫环问题

约瑟夫环问题 (原上原创)
[问题描述] 
编号是1,2,……,n的n个人按照顺时针方向围坐一圈,每个人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个人开始顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他在顺时针方向的下一个人开始重新从1报数,如此下去,直到所有人全部出列为止。设计一个程序来求出出列顺序。 
[基本要求] 
利用顺序存储结构模拟此过程,按照出列的顺序输出各个人的编号。

//顺序结构实现
#include  <iostream.h>
#include  <math.h>
void main()
{
    int n,b,m;                 //从数组的第b个元素开始报://报到m的人出列;
    int A[]={1,2,3,4,5,6,7,8}; //数组A[]用来盛放原序列;
    int B[8];                 //数组B[]用来盛放出列的元素;    
    n=8;                     //数组长度为8;
    cout<<"输入开始报数位置 b :";
    cin>>b;
    cout<<"输入出列口令 m :";
    cin>>m;
    cout<<"原序列为 :";
    for(int i=0;i<n;i++)  cout<<A[i]<<" ";
    cout<<endl;
    i=0;             //变量i用作数组B[]的下标;
    b=(b+m-2)%n;     //b的意义在此改变,它表示在数组A[]中下标为b的位置上的元素出列;
    while(i<n)       //做循环。负责把数组A[]中报m的元素都出列;
    {
        B[i]=A[b];   
        i++;
        if(i==n){   //这一句在B[]满时才执行,负责打印出队序列;
                 cout<<"出队序列为:";
                 for(i=0;i<n;i++)
                     cout<<B[i]<<"  ";
                 return;
                }
        else
        {
              A[b]=0;          //作标记;
              b=(b+1)%n;
              int p=1;
              while(p<m)      //负责找到出队元素前有(m-1)个非零元素;
              {
                 if (A[b]==0)     b=(b+1)%n;
                  else  { b=(b+1)%n; 
                          p++;
                  }
              }  
        }
    
    while(A[b]==0)     //负责找到当前下一个不为零的元素,为下一次出列做准备;
            b=(b+1)%n;
       
    }
}




此帖转自:[url]http://www.programfan.com/team/team.asp?team_id=1346[/url]

回复列表 (共1个回复)

沙发

LZ的解法也行,不过约瑟夫经典问题比较好的方法是运用循环链表。
运用循环链表使得程序具有通用行,随机输入多少个人都行,而且出列的人对应于链表中的结点可以被立即释放掉,不易出错。
一下是我的实现:
参考一下,有不对的地方指点一下:
http://blog.csdn.net/panqiaomu/archive/2007/03/25/1540612.aspx

我来回复

您尚未登录,请登录后再回复。点此登录或注册