题目
堆栈是一种经典的后进先出的线性结构,相关的操作主要有“入栈”(在堆栈顶插入一个元素)和“出栈”(将栈顶元素返回并从堆栈中删除)。本题要求你实现另一个附加的操作:“取中值”——即返回所有堆栈中元素键值的中值。给定 N 个元素,如果 N 是偶数,则中值定义为第 N/2 小元;若是奇数,则为第 (N+1)/2 小元。
输入
输入的第一行是正整数 N(≤105)。随后 N 行,每行给出一句指令,为以下 3 种之一:
Push key
Pop
PeekMedian
其中 key 是不超过 10510^5105 的正整数;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数组,在对数据输入,弹出时通过二分查找到对应位置再插入或者删除。应用了lower_bound函数二分查找不小于输入该数的第一个数,在对应位置插入或者删除。
代码
#include
#include
#include
#include
#include
using namespace std;
string op;
stack<int> st;
vector<int> v;void push(){int data;scanf("%d",&data);st.push(data);v.insert(lower_bound(v.begin(),v.end(),data),data);
}
void pop(){if(st.empty()){cout << "Invalid"<<endl;return ;}int k &#61; st.top();cout << k<<endl;st.pop();v.erase(lower_bound(v.begin(),v.end(),k));
}
void peekm(){if(v.size()&#61;&#61;0){cout << "Invalid"<<endl;return ; }int len &#61; v.size();len&#61;(len&#43;1)/2-1;cout << v[len]<<endl;
}int main(){int n;cin >> n;for(int i &#61; 0;i<n;&#43;&#43;i){cin >> op;if(op &#61;&#61; "Push") push();else if(op &#61;&#61; "Pop") pop();else if(op &#61;&#61; "PeekMedian") peekm();}return 0;
}
运行结果