约瑟夫环问题
问题重述
已知有n个人他们彼此都有编号且互不相同,他们围坐在一起。从第k个人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
第一行由键盘输入一个n,接下来的一行共n个互不相同的数由空格间隔,第三行输入k和m空格间隔要求程序给出他们的出列顺序;
代码实现
#include<stdio.h>
#include<stdlib.h>
int MAXQSIZE; //循环队列长度为(MAXQSIZE-1)
typedef struct{ //定义队列
int*base;
int front;
int rear;
}SqQueue;
void init(SqQueue&L) //创建循环队列并初始化
{
L.base=(int*)malloc(MAXQSIZE*sizeof(int));
if(!L.base) //若创建失败退出程序
exit(0);
L.front=L.rear=0; //初始化队列赋空
}
void input(SqQueue&L) //初始化循环队列 赋初值
{
int a,b;
while(1) //循环输入当按下回车时结束
{
scanf("%d",&a);
L.base[L.rear]=a;
L.rear++;
b=(MAXQSIZE+L.rear-L.front)%MAXQSIZE;
if(getchar()=='\n'||b==MAXQSIZE-1) //判断是否按下回车以及队是否已满
break;
}
}
int DeQueue(SqQueue&L) //出队函数 并返回值
{
int e;
if(L.front==L.rear) //判断队列是否为空若为空提示有关信息
printf("队列已为空\n");
else //不为空队头出队e记录
{
e=L.base[L.front];
L.base[L.front]=0;
L.front++;
if(L.front>=MAXQSIZE)
L.front%=MAXQSIZE;
}
return e;
}
void EnQueue(SqQueue&L,int e) //入队函数
{
if((MAXQSIZE+L.rear-L.front)%MAXQSIZE==MAXQSIZE-1)
printf("队列已满"); //判断队列是否已满若满提示有关信息
else //未满在队尾入队
{
L.base[L.rear]=e;
L.rear++;
if(L.rear>=MAXQSIZE)
L.rear%=MAXQSIZE;
}
}
void output(SqQueue&L,int start,int distance)//总功能函数
{ //接收队列起始位置与间隔调用函数输出结果
int count=1,i,e;
while(L.front!=start-1) //调用出队入队函数将用户输入位置变为队头
{
e=DeQueue(L);
EnQueue(L,e);
}
while(L.front != L.rear) //当队列不为空时循环输出约瑟夫环的序列
{
if(count!=distance) //count计算用户输入的间隔
{ //不满足到队尾
e=DeQueue(L);
EnQueue(L,e);
count++;
}
else //满足则出队
{
e=DeQueue(L);
printf("%d ",e);
count=1;
}
}
printf("\n");
}
int main() //主函数
{
scanf("%d",&MAXQSIZE); //输入序列长度
MAXQSIZE+=1; //循环队列空要空一个空间所以多开一个长度
SqQueue L;
int start,distance;
init(L); //调用初始化函数
input(L); //输入循环队列的值
scanf("%d%d",&start,&distance);
output(L,start,distance);
return 0;
}