Stack is one of the most fundamental data structures, which is based on the principle of Last In First Out (LIFO). The basic operations include Push (inserting an element onto the top position) and Pop (deleting the top element). Now you are supposed to implement a stack with an extra operation: PeekMedian -- return the median value of all the elements in the stack. With N elements, the median value is defined to be the (N/2)-th smallest element if N is even, or ((N+1)/2)-th if N is odd.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (<= 105). Then N lines follow, each contains a command in one of the following 3 formats:

Push key

Pop

PeekMedian

where key is a positive integer no more than 105.

Output Specification:

For each Push command, insert key into the stack and output nothing. For each Pop or PeekMedian command, print in a line the corresponding returned value. If the command is invalid, print "Invalid" instead.

Sample Input:

17
Pop
PeekMedian
Push 3
PeekMedian
Push 2
PeekMedian
Push 1
PeekMedian
Pop
Pop
Push 5
Push 4
PeekMedian
Pop
Pop
Pop
Pop

Sample Output:

Invalid
Invalid
3
2
2
1
2
4
4
5
3
Invalid

分析

这道题蛮有意思的,首先呢,我是直接用vector来实现所有操作,每次peekmedian之前进行排序,结果可想而知,除了第一个测试点和最后一个测试全挂。
然后度娘了一下,好多大神用什么树状数组,去查阅了一些资料,大致对这个数据结构了解了,这就是下面的解法一,其实呢,说通俗点,用这个数组寻找中位数,就是通过树状数组对求数组任意段子数组和的以及删改和增添元素的便利性来求出任何一个数前面比它小的数有多少个来确定该数是否中位数。
当然对于像我这种对树状数组一无所知的小白来说呢,理解树状数组还是有那么一丢丢难度的,所以解法二,则很好的可以帮助大家解决这个问题,解法二的分析这里就直接引用别人的了:
利用set(默认由小到大排序),在Push的时候进行判断然后分别压入s1,s2(s2大于mid,s1小于等于mid); 然后Pop和Push操作的时候分被调整s1,s2以及mid的值。保证s1的大小等于s2的大小或者等于s2的大小+1,这样,s1中的最后一个值就是mid; 注意删除的时候要删除的对象是指针,否则将会把所有值相同的元素都删去

解法一如下

#include <cstdio>
#include <stack>
#define lowbit(i) ((i) & (-i))
const int maxn = 100010;
using namespace std;
int c[maxn];
stack<int> s;
void update(int x, int v) {
for(int i = x; i < maxn; i += lowbit(i))
c[i] += v;
}
int getsum(int x) {
int sum = 0;
for(int i = x; i >= 1; i -= lowbit(i))
sum += c[i];
return sum;
}
void PeekMedian() {
int left = 1, right = maxn, mid, k = (s.size() + 1) / 2;
while(left < right) {
mid = (left + right) / 2;
if(getsum(mid) >= k)
right = mid;
else
left = mid + 1;
}
printf("%d\n", left);
}
int main() {
int n, temp;
scanf("%d", &n);
char str[15];
for(int i = 0; i < n; i++) {
scanf("%s", str);
if(str[1] == 'u') {
scanf("%d", &temp);
s.push(temp);
update(temp, 1);
} else if(str[1] == 'o') {
if(!s.empty()) {
update(s.top(), -1);
printf("%d\n", s.top());
s.pop();
} else {
printf("Invalid\n");
}
} else {
if(!s.empty())
PeekMedian();
else
printf("Invalid\n");
}
}
return 0;
}

解法二如下

#include<iostream>
#include<stack>
#define lowbit(i) ((i)&(-i))
using namespace std;
const int maxn=100005;
int c[maxn];
stack<int> st;
void update(int x,int v){
for(int i=x;i<maxn;i+=lowbit(i))
c[i]+=v;
}
int getsum(int x){
int sum=0;
for(int i=x;i>=1;i-=lowbit(i))
sum+=c[i];
return sum;
}
void PeekMedian(){
int left=1,right=maxn,mid,k=(st.size()+1)/2;
while(left<right){
mid=(left+right)/2;
if(getsum(mid)>=k)
right=mid;
else
left=mid+1;
}
printf("%d\n",left);
}
int main(){
int n,num,temp;
cin>>n;
char order[15];
for(int i=0;i<n;i++){
scanf("%s",order);
if(order[1]=='u'){
scanf("%d",&num);
st.push(num);
update(num,1);
}else if(order[1]=='e'){
if(st.size()==0)
printf("Invalid\n");
else
PeekMedian();
}else if(order[1]=='o'){
if(st.size()==0)
printf("Invalid\n");
else{
temp=st.top();
printf("%d\n",temp);
st.pop();
update(temp,-1);
}
}
}
return 0;
}

PAT 1057. Stack的更多相关文章

  1. PAT 1057 Stack [难][树状数组]

    1057 Stack (30)(30 分) Stack is one of the most fundamental data structures, which is based on the pr ...

  2. PAT 1057. Stack (30)

    题目地址:http://pat.zju.edu.cn/contests/pat-a-practise/1057 用树状数组和二分搜索解决,对于这种对时间复杂度要求高的题目,用C的输入输出显然更好 #i ...

  3. PAT甲级1057. Stack

    PAT甲级1057. Stack 题意: 堆栈是最基础的数据结构之一,它基于"先进先出"(LIFO)的原理.基本操作包括Push(将元素插入顶部位置)和Pop(删除顶部元素).现在 ...

  4. PAT 甲级1057 Stack (30 分)(不会,树状数组+二分)*****

    1057 Stack (30 分)   Stack is one of the most fundamental data structures, which is based on the prin ...

  5. pat 甲级 1057 Stack(30) (树状数组+二分)

    1057 Stack (30 分) Stack is one of the most fundamental data structures, which is based on the princi ...

  6. PAT (Advanced Level) 1057. Stack (30)

    树状数组+二分. #include<iostream> #include<cstring> #include<cmath> #include<algorith ...

  7. PAT甲级1057 Stack【树状数组】【二分】

    题目:https://pintia.cn/problem-sets/994805342720868352/problems/994805417945710592 题意:对一个栈进行push, pop和 ...

  8. PAT甲级题解-1057. Stack (30)-树状数组

    不懂树状数组的童鞋,正好可以通过这道题学习一下树状数组~~百度有很多教程的,我就不赘述了 题意:有三种操作,分别是1.Push key:将key压入stack2.Pop:将栈顶元素取出栈3.PeekM ...

  9. PAT 甲级 1057 Stack

    https://pintia.cn/problem-sets/994805342720868352/problems/994805417945710592 Stack is one of the mo ...

随机推荐

  1. java问题解读,String类为什么是final的

    一.理解final 望文生义,final意为“最终的,最后的”,我理解为“不能被改变的”,它可以修饰类.变量和方法. 所以我是否可以理解为被它所修饰的类.变量和方法都不能被改变呢?答案是”是“,因为有 ...

  2. P1402 酒店之王 网络流

    大水题,我自己瞎做就做出来了,没啥说的,zz建图,就是板子. 题干: 题目描述 XX酒店的老板想成为酒店之王,本着这种希望,第一步要将酒店变得人性化.由于很多来住店的旅客有自己喜好的房间色调.阳光等, ...

  3. cf2.25

    T1 题意:判断给出的数中有多少不同的大于的数. content:傻逼题,5min手速 T2 题意:给出p.y,输出y~p+1中最大一个不是2-p的倍数的数. content:答案很简单,但是很难想到 ...

  4. Mybatis 代码自动生成(generatorConfig.xml配置)

    博客推荐: Mybatis最入门---代码自动生成(generatorConfig.xml配置) MyBatis Generator generatorConfig.xml配置详解 pom.xml&l ...

  5. PCB genesis孔符制作实现方法

    一.先看genesis原始孔符 孔符的作用:用于表示孔径的大小的一种代号, 当孔径检测时,可以按分孔图中的孔符对应的孔径尺寸对孔径检测. 在实际PCB行业通常不使用原始(图形)孔符,而使用字母孔符(如 ...

  6. Frequent values(线段树+离散化)

    http://poj.org/problem?id=3368 题意:给出一个非降序排列的整数数组,对于询问(i,j),输出区间[i,j]中出现最多的值的次数. 思路:经典的RMQ,不过我用线段树做的. ...

  7. JS连续滚动幻灯片:原理与实现

    什么是连续滚动幻灯片?打开一些网站的首页,你会发现有一块这样的区域:一张图片,隔一段时间滑动切换下一张:同时,图片两端各有一个小按钮,供你手动点选下一张:底部有一排小圆圈,供你选定特定的某帧图片.这就 ...

  8. Java的Thread.currentThread().getName() 和 this.getName() 以及 对象.getName()区别???

    最近在看Java多线程这本书,但是发现里面有个概念自己搞不清楚.就是Thread.currentThread().getName() 和 this.getName() 以及 对象.getName()区 ...

  9. Android Studio 关于build.gradle配置问题

    当导入一个Android Project时,会出现很多版本的问题,导入前先删除 .idea文件 .gradle文件 ,gradle文件(与.gradle区分,导入时Android Studio会提示重 ...

  10. Android 自己搭建一个直播系统吧

    服务端用 SRS(Simple Rtmp Server),在这里下载simple-rtmp-server需要Linux系统最好是Ubuntu,装个Ubuntu虚拟机就行了在Linux里,解压缩SRS ...