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 (-th smallest element if N is even, or (-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 (≤). 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 1.

Output Specification:

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

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

数组数据是随时都在进行输入与删除的,让你实时反馈数组中的中位数:
使用分块思想
1、一般来说,为了达到高效率的目的,对一个有N个元素的有序序列来说,除最后一块外,其余每块中元素的个数都应当为 | √N | (此处为向下取整,方便程序实现),于是块数为[√N](此处为向上取整)。这样就把有序序列划分为[√N]块,其中每块中元素的个数不超过 | √N | 。
考虑到序列中的元素都是不超过105的非负整数,因此不妨设置一个hash数组table[100001],其中table[x]表示整数x的当前存在个数;
接着,借助分块思想,从逻辑上将0~10分为 | √(105 + 1) |= 317块,其中每块的元素个数为316。逻辑上进行分块的结果如下:
0,1,2.…,314,315为第0块;
316,317…,630,631为第1块。
99856,99857,…,100000为第316块。
这样分块有什么用呢?可以定义一个统计数组block[317],其中block[i]表示第i块中存在的元素个数。于是假如要新增一个元素x,就可以先计算出x所在的块号为x / 316,然后让block[x / 316]加1,表示该块中元素个数多了1;同时令table[x]加1,表示整数x的当前存
在个数多了1。
例如想要新增334这个元素,就可以通过334 / 316 = 1算出元素334所在的块号为1,然后令block[1]++,表示1号块增加了一个元素,并令table[334] + 1,表示元素334的存在个数多了1。
同理,如果想要删除一个元素x,只需要让block[x / 316]和table[x]都减1即可。显然,新增与删除元素的时间复杂度都是O(1)。
接着来看如何查询序列中第K大的元素是什么。
首先,从小到大枚举块号,利用block数组累加得到前i - 1块中存在的元素总个数,然后判断加入i号块的元素个数后元素总个数能否达到K。如果能,则说明第K大的数就在当前枚举的这个块中,此时只需从小到大遍历该块中的每个元素(其中i号块的第一个元素是i * 316),利用table数组继续累加元素的存在个数,直到总累计数达到K,则说明找到了序列第K大的数。显然整体思路是先用O(√N)的时间复杂度找到第K大的元素在哪一块,然后再用0(√N)的时间复杂度在块内找到这个元素,因此单次查询的总时间复杂度为0(√N)。

 #include <iostream>
#include <stack>
#include <string>
#include <cmath>
using namespace std;
int N, num, table[], block[];//数的个数,块中数的个数
int main()
{
cin >> N;
stack<int>s;
string str;
for (int i = ; i < N; ++i)
{
cin >> str;
if (str == "Pop")
{
if (s.size() > )
{
cout << s.top() << endl;
table[s.top()]--;
block[s.top() / ]--;
s.pop();
}
else
cout << "Invalid" << endl;
}
else if (str == "Push")
{
cin >> num;
s.push(num);
table[num]++;
block[num / ]++;
}
else
{
if (s.size() > )
{
int mid = s.size() % == ? s.size() / : (s.size() + ) / ;
int t = , k = ;
while (k + block[t] < mid) k += block[t++];
int num = t * ;
while (k + table[num] < mid)k += table[num++];
cout << num << endl;
}
else
cout << "Invalid" << endl;
}
}
return ;
}

PAT甲级——A1057 Stack的更多相关文章

  1. PAT甲级1057. Stack

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

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

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

  3. PAT 甲级 1057 Stack

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

  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甲级题解(慢慢刷中)

    博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6102219.html特别不喜欢那些随便转载别人的原创文章又不给 ...

  7. PAT甲级1127. ZigZagging on a Tree

    PAT甲级1127. ZigZagging on a Tree 题意: 假设二叉树中的所有键都是不同的正整数.一个唯一的二叉树可以通过给定的一对后序和顺序遍历序列来确定.这是一个简单的标准程序,可以按 ...

  8. PAT甲级考前整理(2019年3月备考)之二,持续更新中.....

    PAT甲级考前整理之一网址:https://www.cnblogs.com/jlyg/p/7525244.html,主要总结了前面131题的类型以及易错题及坑点. PAT甲级考前整理三网址:https ...

  9. PAT甲级专题|树的遍历

    PAT甲级专题-树的遍历 涉及知识点:树.建树.深度优先搜索.广度优先搜索.递归 甲级PTA 1004 输出每一层的结点,邻接表vector建树后.用dfs.bfs都可以边搜边存当前层的数据, #in ...

随机推荐

  1. 怎样使用github?(转)

    怎样使用github?(转) 转自: 怎样使用 GitHub? - 知乎https://www.zhihu.com/question/20070065 珊姗是个小太阳 ❤努力做最胖//bang的健身博 ...

  2. C#实现程序开机启动

    如何用c#实现开机启动?其实用c#实现程序的开机启动大致有两种方法,就是写入注册表或者采用服务程序,最近一直研究着用C#来操作注册表,下面介绍的方法便是用注册表来实现程序随开机启动(高手就不用看了,嘿 ...

  3. HTTP协议基础篇(帮助理解)

    用uml 来描述一个功能是怎样按照时间的顺序完成的 实际的需求(配置网站/配置虚拟主机) 步骤 (1) 打开 apache/conf/httpd.conf 文件 (2)找到hosts文件 c:/win ...

  4. vue 图片懒加载v-lazy

    搬运自:https://blog.csdn.net/twodogya/article/details/80223331 vue v-lazy官方API:https://www.npmjs.com/pa ...

  5. python pip安装扩展报错

    1.安装tldr报错 (1)报错详情: [root@linuxnode1 ~]# pip install tldrCollecting tldr Downloading https://files.p ...

  6. [JZOJ1320] 【Usaco2009 gold 】拯救奶牛

    题目 题目大意 一个三角形的网格图,三角形与其有共同边的三角形相连. 起点到所有终点的最短距离. 思考历程 数据看起来还挺大的,所以不是什么图论算法. 这显然是一个结论题. 什么结论? 然后我就开始推 ...

  7. Java英语面试题(核心知识篇)

    Java英语面试题(核心知识篇) Question: What is transient variable?Answer: Transient variable can't be serialize. ...

  8. Windows安全证书生成方法(开发者证书)

    首先,查看本机安装的证书可在“运行”中输入:certmgr.msc 一.win8.8.1.win10系统,使用管理员powershell创建证书: (1)利用如下命令来创建证书并获取到其指纹 New- ...

  9. Android数据适配器Adapter简介

    1.简介 Adapter是用来帮助填充数据的中间桥梁,简单点说就是:将各种数据以合适的形式显示到view上,在常见的View(List View,Grid View)等地方都需要用到Adapter! ...

  10. Java - 关于覆盖和重写的总结

    公众号偶然看到的一个帖子,构造方法,类方法,final方法,哪些能覆盖,哪些能重载,初学时也是被这些术语搞的很迷糊 现在有时间了对这些做一个总结.全是自己的语言,可能不是很全面,表达意思应该够清楚 一 ...