约瑟夫问题:有 N 个人围成一圈,每个人都有一个编号,编号由入圈的顺序决定,第一个入圈的人编号为 1,最后一个为 N,从第 k (1<=k<=N)个人开始报数,数到 m (1<=m<=N)的人将出圈,然后下一个人继续从 1 开始报数,直至所有人全部出圈,求依次出圈的编号。
#include<iostream>
using namespace std;
struct cQueue
{
int *a=NULL;
int maxSize;
int front,rear;
} ;
void init(cQueue* q, int sz)
{
q->a=new int[sz];
q->maxSize=sz;
q->front=0;
q->rear=0;
}
void flush(cQueue* q)
{
delete q->a;
}
bool empty(cQueue* q)
{
return q->front==q->rear;
}
bool full(cQueue* q)
{
return q->front==(q->rear+1)%q->maxSize;
}
void clear(cQueue* q)
{
q->front=0;
q->rear=q->front;
}
int size(cQueue* q)
{
return (q->rear-q->front+q->maxSize)%q->maxSize;
}
bool push(cQueue* q, int x)
{
if(full(q))return false;
q->a[q->rear]=x;
q->rear=(q->rear+1)%q->maxSize;
return true;
}
void pop(cQueue* q)
{
q->front=(q->front+1)%q->maxSize;
}
int front(cQueue* q)
{
return q->a[q->front];
}
int main()
{
cQueue q;
cQueue ou;
cQueue *q1=&q;
cQueue *out=&ou;
cout<<"请分别输入总人数,开始的号数和每几个人淘汰一次"<<endl;
int n,m,w;//n:num of people;m:start people;w:outpost num;
cin>>n>>m>>w;
init(q1,n+5);
init(out,n+5);
for(int i=1;i<=n;i++)
{
push(q1,i);
}
int i=0;
int w1=w;
while(w1!=1){
push(q1,front(q1));
pop(q1);
w1--;
}
while(size(q1)!=1)
{
i++;
if(i%w!=0){
push(q1,front(q1));
pop(q1);
}
else{
push(out,front(q1));
pop(q1);
}
}
int n0=size(out);
cout<<"出列顺序为: ";
for(int j=0;j<n0;j++)
{
cout<<front(out)<<' ';
pop(out);
}
cout<<endl;
cout<<"最后剩余的人为"<<front(q1)<<"号";
flush(q1);
flush(out);
}