josephus 问题的数组解法

问题提出:试编写一个求解Josephus问题的函数。用整数序列123...,n表示顺序围坐在圆桌周围的人,并采用数组表示作为求解过程中使用的数据结构。然后使用n=9,s=1,m=5,以及n=9,s=1,m=0,或者n=9,s=1,m=10作为输入数据,检查你的程序的正确性和健壮性。


我的思路:

1.n个人围城一圈,则创建一个数组来表示这些人,并且给他们编号。从a[0]到a[n-1]

2.若是从第s个人开始报数,则这个人的数组下标应该是s-1。

3.采用一个N-1次的循环来逐个剔除圆圈中的人,并且把剔除的人逐个排在数组里(从a[n-1]一直到a[1])

4.采用i=(i+m-1)%k这个方法来定位我们要找剔除的人所在的下标位置。

程序:

#include "stdafx.h"

#include<stdlib.h>

#using <mscorlib.dll>

#include <iostream>

using namespace std;

 

void Josephus(int a[],int n,int s,int m);

int _tmain()

{      int i, n,m,s;

            cout<<"假设有n个人坐在圆桌的周围:"<<endl;

            cout<<"从第s个人开始数起,到第m个人的时候,出局"<<endl;

            cout<<"请输入n,s,m的值:"<<"";

            cin>>n>>s>>m;

            cout<<endl;

            int *a; //定义一个动态数组

            a=new int[n];

            if(a[n] ==NULL)

               {

                    cerr<<"内存分配错误!"<<endl;

               }

            if(m==0){

                          cerr<<"m=0是无效的参数!"<<endl;

                          cout<<"再次输入m的值:"<<endl;

                           cin>>m;

                        }

            Josephus(a,n,s,m);

            cout<<endl;

            cout<<"n个人出局的顺序:"<<endl;

            for(i=0;i<n;i++)  cout<<a[i]<<'/t';

            cout<<endl;

            delete[] a;

            return 0;

}  

  void Josephus(int a[],int n,int s,int m)//n个人围坐在一个圆桌周围,从第s个人开始报数,数到第m个人,让他出局

{

           int i,j,k,tmp;

           for(i=0;i<n;i++) a[i]=i+1;   //初始化,执行n次

       i=s-1;               //报名起始位置

           for(k=n;k>=1;k--){         //逐个出局,执行n-1次

                  if(i==k) i=0;

                  i=(i+m-1)%k;       //寻找出局的位置

                  if(i!=k-1){      

                     tmp=a[i];          //出局者交换到第k-1位置

                     for(j=i;j<k-1;j++) a[j]=a[j+1];//挪位,从出局者后面那个为出局者开始改变下标,每个下标减1.

             a[k-1]=tmp;

                  }

     }

       for(k=0;k<n/2;k++){        //全部逆置,得到出局序列

              tmp=a[k];

              a[k]=a[n-k-1];

              a[n-k-1]=tmp;

         }

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值