【团体天梯赛/PTA】7-182 特殊堆栈 (30 分)
堆栈是一种经典的后进先出的线性结构,相关的操作主要有“入栈”(在堆栈顶插入一个元素)和“出栈”(将栈顶元素返回并从堆栈中删除)。本题要求你实现另一个附加的操作:“取中值”——即返回所有堆栈中元素键值的中值。给定 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
新学知识点:
Vector容器:
- pop_bakc()删除最后一个元素,back()显示最后一个元素
- Vector容器使用sort排序,sort(v.begin(),v.end())
- lower_bound函数:lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
- upper_bound函数:从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
- insert支持地址插入,insert(it,data)
解题思路:
- 使用string类型字符串读取命令:Push,Pop,PeekMedian
- 使用两个vector容器,容器v记录正常排序,容器temp记录从小到大排序
- Push指令:将key同时读入到两个容器中,此处注意temp的读入,读入的同时给temp排序,故使用lower_bound函数查找一个大于等于data的位置,使用insert读入。
- Pop指令:同上,同时跳出,但需要注意不改变temp的排序,使用erase清除
- PeekMedian指令:输出,因为下标从0开始。故当temp的长度len为偶数时,输出下标为len/2-1的元素,奇数输出下标为len/2的元素
- 使用size()来判断容器是否为空,0为空,非0不为空。
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
using namespace std;
int main()
{
vector<int>v, temp;
vector<int>::iterator it;
int n,t; cin >> n;
string cmd;
while (n--)
{
cin >> cmd;
if (cmd == "Push") //入栈
{
cin >> t;
v.push_back(t);
it = lower_bound(temp.begin(), temp.end(), t);
temp.insert(it, t);
}
else if (cmd == "Pop") //输出最后一个值
{
if (v.empty()) cout << "Invalid" << endl;
else
{
cout << v[v.size()-1] << endl;
it = lower_bound(temp.begin(), temp.end(), v[v.size() - 1]);
temp.erase(it);
v.pop_back();
}
}
else if (cmd == "PeekMedian")//输出中值
{
if (v.empty()) cout << "Invalid" << endl;
else
{
int len = temp.size();
if (len % 2 == 0) cout << temp[len / 2 - 1] << endl;
else cout << temp[len / 2] << endl;
}
}
}
return 0;
}