堆栈是一种经典的后进先出的线性结构,相关的操作主要有“入栈”(在堆栈顶插入一个元素)和“出栈”(将栈顶元素返回并从堆栈中删除)。本题要求你实现另一个附加的操作:“取中值”——即返回所有堆栈中元素键值的中值。给定 N 个元素,如果 N 是偶数,则中值定义为第 N/2 小元;若是奇数,则为第 (N+1)/2 小元。
输入格式:
输入的第一行是正整数 N(≤10^5)。随后 N 行,每行给出一句指令,为以下 3 种之一:
Push key Pop PeekMedian
其中 key 是不超过 10^5 的正整数;Push 表示“入栈”;Pop 表示“出栈”;PeekMedian 表示“取中值”。
输出格式:
对每个 Push 操作,将 key 插入堆栈,无需输出;对每个 Pop 或 PeekMedian 操作,在一行中输出相应的返回值。若操作非法,则对应输出 Invalid。
输入样例:
17 Pop PeekMedian Push 3 PeekMedian Push 2 PeekMedian Push 1 PeekMedian Pop Pop Push 5 Push 4 PeekMedian Pop Pop Pop Pop
输出样例:
Invalid Invalid 3 2 2 1 2 4 4 5 3 Invalid
#include <iostream>
#include <algorithm>
#include <string>
#include <stack>
#include <vector>
using namespace std;
stack<int> box; //栈
vector<int> num; //找中值
int main()
{
int n; cin >> n;
while (n--)
{
string str; cin >> str;
if (str[1] == 'o')
{
if (box.empty())
cout << "Invalid" << endl;
else
{
cout << box.top() << endl;
auto it = find(num.begin(), num.end(), box.top());
num.erase(it); //同步删除栈顶元素
box.pop();
}
}
else if (str[1] == 'e')
{
if (box.empty())
cout << "Invalid" << endl;
else //找到元素个数与中值下标的关系
cout << num[(num.size() - 1) / 2] << endl;
}
else
{
int key; cin >> key;
box.push(key);
auto it = upper_bound(num.begin(), num.end(), key);
num.insert(it, key); //vector一直有序,逐一插入新元素,用sort函数会超时
}
}
return 0;
}
注意事项:
中值指中位数,需要对入栈元素升序排序,而直接使用sort进行排序会导致测试点1、2、3运行超时,需要另辟蹊径。
如有问题,欢迎提出。