THU2015 fall 2-4 Queap
描述
通过扩展已实现的基本数据结构,模拟更为复杂的数据结构,是一种常见而实用的技巧。这里,我们将利用栈结构,来模拟一种功能增强的队列。
具体来说,你必须首先实现一个元素类型为int的栈,该栈能且只能支持以下操作接口:
bool empty(); //判断是否栈空
void push(int); //向栈中压入一个整数
int pop(); //弹出栈顶元素,并返回其数值
int top(); //仅获取栈顶元素的值,但不弹出
接下来,你必须借助以上栈结构,模拟所谓的队堆(queap)结构,它至少支持以下操作接口:
void enqueue(int); //新元素作为尾元素入队
int dequeue(); //队首元素出队,并返回其数值(调用时输入数据保证队列非空)
int min(); //返回队列内的最小元素(调用时输入数据保证队列非空)
可见,这种结构之所以称作队堆,是因为它兼具一定的队列(queue)和堆(heap)的功能。
最后,你还需要通过一系列真实的查询和修改操作,对所实现的队堆结构进行测试。
输入
第一行仅含一个整数,即查询和修改操作的总数n。
以下n行,依次给出对初始为空的队堆所实施的n次操作。各行的格式为以下几种之一:
1. E x //即enqueue(int x)
2. D //即x = dequeue()
3. M //即x = min()
输出
若D和M操作共计m <=n 次,则共m行,依次给出各D/M操作所对应的返回值。
输入样例
9
E 5
E 6
M
E 2
M
D
M
D
M
输出样例
5
2
5
2
6
2
限制
0 <=m<= n <= 1,000,000,m,n均为整数
所有元素需要存储在底层栈中,即除了底层栈之外的空间使用应为O(1)。
实现队堆所用到的栈的个数应为常数。
不能向该存储数据的栈中添加其他public成员函数(构造、析构函数除外)或变量。
你可以根据需要包装该底层栈形成其他数据结构,其他不存储数据的结构的成员函数和变量可以自由选取。
请通过拓展给定的模板http://dsa.cs.tsinghua.edu.cn/oj/attachment/3ffa/3ffaf6a8704e3d075df704ff9cbe9100ab2df8d4.cpp来实现。
//模板
class Stack
{
public:
//注意:你不能添加更多的public函数或变量,如有需要可添加析构函数
Stack()
{
}
bool empty();
void push(int);
int pop();
int top();
private:
//此处可以扩展
};
Stack::Stack()
{
}
bool Stack::empty()
{
}
void Stack::push(int value)
{
}
int Stack::pop()
{
}
int Stack::top()
{
}
class Queap
{
public:
Queap();
void enqueap(int);
int dequeap();
int min();
private:
};
Queap::Queap()
{
}
void Queap::enqueap(int value)
{
}
int Queap::dequeap()
{
}
int Queap::min()
{
}
int main()
{
return 0;
}
时间:1sec
空间:256MB
代码如下:
#include <stdio.h>
const int SZ = 1 << 20; //提升IO buff
struct fastio{
char inbuf[SZ];
char outbuf[SZ];
fastio(){
setvbuf(stdin, inbuf, _IOFBF, SZ);
setvbuf(stdout, outbuf, _IOFBF, SZ);
}
}io;
using namespace std;
#define N 1000001
#define INF 2<<32
int minVal(int x, int y)
{
return x < y ? x : y;
}
class Stack
{
public:
//注意:你不能添加更多的public函数或变量,如有需要可添加析构函数
Stack();
~Stack();
bool empty();
void push(int);
int pop();
int top();
private:
//此处可以扩展
int *stack;
int loc;
int capacity;
};
Stack::Stack()
{
capacity = N;
stack = new int[capacity];
//*stack = INF;
loc = 0;
}
Stack::~Stack()
{
delete[] stack;
}
bool Stack::empty()
{
if (0 == loc) return true;
else return false;
}
void Stack::push(int value)
{
stack[++loc] = value;
}
int Stack::pop()
{
if (!empty()) return stack[loc--];
else return -1;
}
int Stack::top()
{
return stack[loc];
}
class Queap
{
public:
Queap();
void enqueap(int);
int dequeap();
int min();
private:
Stack s1, s11, s2, s22;
};
Queap::Queap()
{
while (!s1.empty()) s1.pop();
while (!s11.empty()) s11.pop();
while (!s2.empty()) s2.pop();
while (!s22.empty()) s22.pop();
}
void Queap::enqueap(int value)
{
s2.push(value);
s22.push(minVal(value, s22.empty() ? value : s22.top()));
}
int Queap::dequeap()
{
if (s1.empty())
{
while (!s2.empty())
{
int tmp = s2.top();
s22.pop();
s1.push(s2.pop());
s11.push(minVal(tmp, s11.empty() ? tmp : s11.top()));
}
}
s11.pop();
return s1.pop();
}
int Queap::min()
{
if (s1.empty())
{
while (!s2.empty())
{
int tmp = s2.top();
s1.push(s2.pop());
s22.pop();
s11.push(minVal(tmp, s11.empty() ? tmp : s11.top()));
}
}
return minVal(s11.top(), s22.empty() ? s11.top():s22.top());
}
int main()
{
Queap q;
int n;
scanf("%d", &n);
while (n--)
{
char c;
while (scanf("%c", &c) && c != 'E' && c != 'D' && c != 'M');
switch (c)
{
case 'E':
int value;
scanf("%d", &value);
q.enqueap(value);
break;
case 'D':
printf("%d\n", q.dequeap());
break;
case 'M':
printf("%d\n", q.min());
break;
}
}
return 0;
}