约瑟夫环问题

问题描述:

n个人围成一圈,从第k个人开始报数(0<k<n)报到m(m>0)的人出列,出列的人的下一个人继续报数,每到m的人就出列,求最后出列的人的编号。

Input:n= 3  k = 1  m= 3        

Output:  2

 

实现方法:

有两种实现方法,可以采用数组也可以采用链表

方法一: 用数组存放数据

在类ArraySort的头文件中定义以下两个方法

 void YueseFuArr(int arr1[],int result[],int len,int m,int k);
 void TestOfYueseFuArr();

然后在cpp文件中实现如下方法:

void ArraySort::YueseFuArr(int arr1[],int result[],int len, int m,int k)
{
 int i=-1,n=0;
 for (int i0=0;i0<k-1;i0++)
 {
  i++;
 }
 while(len--){
  for (int j=0;j<m;)
  {
   i=(i+1)%m;
   if (arr1[i]!=0)
   {
    j++;
   }
  }
  result[n++] = arr1[i];
  arr1[i] = 0;
 }

 cout<<"结果:"<<endl;
 for (int i=0;i<n;i++)
 {
  cout<<result[i]<<" ";
 }
 cout<<endl;
}

void ArraySort::TestOfYueseFuArr(){
 int m,n,k;
 cout<<"n=";
 cin>>n;
 cout<<"k=";
 cin>>k;
 cout<<"m=";
 cin>>m;
 int *arr1 = new int[n];
 int *result = new int[n];
 
 cout<<"原始数组:"<<endl;
 for (int i=0;i<10;i++)
 {
  arr1[i] = i+1;
  cout<<arr1[i]<<" ";
 }
 cout<<endl;
 
 YueseFuArr(arr1,result,n,m,k);
 
}

 

在主函数中调用TestOfYueseFuArr方法即可。

运行结果如下:

n=10
k=2
m=10
原始数组:
1 2 3 4 5 6 7 8 9 10
结果:
1 2 4 7 3 10 6 8 5 9

 

 

方法二:用链表存储数据

首先定义数据结构:

typedef struct Node

 int num;
 struct Node *next;
}LinkList;

在ListOperator类的头文件中定义如下方法:

 LinkList *creatCircle(int n);//创造环装链表
 void fun(LinkList *L,int k,int m);逐个输出出列的编号
 int TestOfYueSeFuHuan();//测试用例

 //约瑟夫环相关操作

LinkList* ListOperator::creatCircle(int n){
 LinkList *p,*q,*head;
 int i=1; 
 //p=(LinkList *)malloc(sizeof(LinkList));
 p = new LinkList();
    p->num=i;
 head=p;
    for(i=2;i<=n;i++)
    {
       // q=(LinkList *)malloc(sizeof(LinkList));
  q = new LinkList();
        q->num=i;
        p->next=q;
        p=q; 
    }
    p->next=head;          /*使链表尾指向链表头 形成循环链表*/
   return head;
}

void ListOperator::fun(LinkList *L,int k,int m)
{
 int i;
 LinkList *p,*s,*q;
 p=L;
 cout<<"出列顺序为:"<<endl;

 for(i=1;i<k;i++)
 {
  q=p;
  p=p->next;
 }
 while(p->next!=p)
 {  
  for(int j=1; j<m;j++){
   q=p;
   p=p->next;
  }
  cout<<p->num<<" ";
  s=p;
  q->next=p->next;
  p=p->next;
  free(s);
 }
 cout<<p->num<<endl;
}

int ListOperator::TestOfYueSeFuHuan(){
 LinkList *L;
 int n, m,k;
 cout<<"n = ";
 cin>>n;
 cout<<"m = ";
 cin>>m;
 cout<<"k = ";
 cin>>k;
 L=creatCircle(n);

 fun(L,k,m); 
 return 0;
}

 

n = 10
m = 10
k = 1
出列顺序为:
10 1 3 6 2 9 5 7 4 8

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

daiyier

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值