循环队列模拟约瑟夫问题(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); }