整理的目的是明确插入算法和查询算法的时间复杂度。
找到数组a中与x相同的值,时间复杂度最快是logn的,用的是二分的思想,我们可以选择lower_bound来使用,lower_bound:lower_bound(a.begin(),a.end(),x)返回值是指针或者迭代器
因为我们需要拿到中值,则需要选择使用sort或者插入维护,对于sort最快是onlogn,而insert是先查询,在移动,整体是on的,所以对于经常性的插入数据,我们选择用lower_bound和insert对vector进行维护
L3-002 特殊堆栈 (30分)
堆栈是一种经典的后进先出的线性结构,相关的操作主要有“入栈”(在堆栈顶插入一个元素)和“出栈”(将栈顶元素返回并从堆栈中删除)。本题要求你实现另一个附加的操作:“取中值”——即返回所有堆栈中元素键值的中值。给定 N 个元素,如果 N 是偶数,则中值定义为第 N/2 小元;若是奇数,则为第 (N+1)/2 小元。
输入格式:
输入的第一行是正整数 N(≤105)。随后 N 行,每行给出一句指令,为以下 3 种之一:
Push key
Pop
PeekMedian
其中 key
是不超过 105 的正整数;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<cstdio>
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
#define MAXN 1000015
int vec[MAXN];
vector<int> a;
string temp;
int cnt,t,x;
int main()
{
cin>>t;
vector<int>::iterator it;
int l,r,mid;
while(t--)
{
cin>>temp;
if(temp.back() == 'p')
{
if(!cnt) printf("Invalid\n");
else
{
it = lower_bound(a.begin(),a.end(),vec[cnt-1]);
a.erase(it);
printf("%d\n",vec[--cnt]);
}
}
else if(temp.back() == 'h')
{
cin>>x;
vec[cnt] = x;
it = lower_bound(a.begin(),a.end(),x);
a.insert(it,x);
cnt++;
}
else if(temp.back() == 'n')
{
if(!cnt) printf("Invalid\n");
else if(cnt % 2 == 1) printf("%d\n",a[cnt/2]);
else if(cnt % 2 == 0) printf("%d\n",a[cnt/2-1]);
}
}
return 0;
}