链队列(带头结点)模板简单应用算法设计:猴子选大王
作者: 冯向阳时间限制: 1S章节: DS:队列
截止日期: 2022-06-30 23:55:00
问题描述 :
目的:使用C++模板设计链队列的抽象数据类型(ADT)。并在此基础上,使用链队列ADT的基本操作,设计并实现简单应用的算法设计。
内容:(1)请参照单链表的ADT模板,设计链队列的抽象数据类型。(由于该环境目前仅支持单文件的编译,故将所有内容都集中在一个源文件内。在实际的设计中,推荐将抽象类及对应的派生类分别放在单独的头文件中。参考教材、课件,以及网盘中的单链表ADT原型文件,自行设计链队列的ADT。)
注意:链队列带头结点。
(2)ADT的简单应用:使用该ADT设计并实现应用链队列的算法设计。
应用:猴子选大王是一个小游戏,其规则是:假设n个猴子围成一堆,取数字m为将要被淘汰的数字,从第一个猴子开始数,数到数字m时,则该猴子出列,被淘汰,然后从被淘汰的猴子的下一个开始数,再数到数字m时,这个猴子也被淘汰,从下一个开始数,依次进行,直到剩下一个猴子结束。该猴子即猴子大王。
要求设计一个算法,使用链队列,设计并实现按照以上规则进行选择猴王的算法。为简单起见,直接输出猴王的序号即可,无需保存。
参考函数原型:
template<class ElemType>
void monkey_king( LinkQueue<ElemType> S, int n, int m );
输入说明 :
第一行:猴子的数目n
第二行:淘汰数字m
输出说明 :
第一行:猴王的序号
输入范例 :
30
4
输出范例 :
6
#include<iostream>
using namespace std;
int n,ss;
typedef struct Queue
{
int* base;
int rear;
int front;
}Queue;
void EnQueue(Queue* Q,int x)
{
Q->base[Q->rear] = x;
Q->rear = (Q->rear + 1) % n;
}
int DeQueue(Queue* Q)
{
int e = Q->base[Q->front];
Q->front = (Q->front + 1) % n;
return e;
}
int QueueLength(Queue* Q)
{
return (Q->rear - Q->front + n) % n;
}
int Monkey()
{
Queue Q;
Q.base = new int[100001];
Q.front = Q.rear = 0;
for (int i = 1; i < n; i++)
{
EnQueue(&Q, i);
}
int p = 0;
while (QueueLength(&Q) > 1)
{
p++;
if (p == ss)
{
DeQueue(&Q);
p = 0;
}
else
{
EnQueue(&Q, DeQueue(&Q));
}
}
return Q.base[Q.front];
}
int main()
{
cin>>n>>ss;
n++;
int king=Monkey();
cout<<king<<" "<<endl;
return 0;
}