快捷搜索: 王者荣耀 脱发

循环队列模拟约瑟夫问题(C++)

约瑟夫问题:有 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);
}
经验分享 程序员 微信小程序 职场和发展