主要内容是栈和队列。

1.  栈

运算受到限制的线性表。只允许从一端进行插入和删除等操作。这一端便是栈顶,另一端便是栈底。
其实可以把栈想象层任何有底无盖的柱状的容器。。。毕竟栈满足后进先出的特性。计算机当中调用函数时,中间结果便会保存到「系统栈」中。递归过程也需要栈的协助 。
实现:STL or 手写(请参照一本通 or 课件)
一般操作:判断栈空/满、入栈、出栈,判断栈的大小(请参照一本通 or 课件)
1.1 单调栈
顾名思义,保证内部元素单调(单增或单减)的栈。我们只要在插入新元素的时候,将栈顶所有在插入新元素后不满足单调的元素依次弹出,再插入新元素即可。
对于单调性可以这么理解:所有加入单调队列/单调栈的元素有一个「价值」和「时效性」。价值即为元素的值,时效性则为元素加入的时间。元素加入的时间越久远就越有可能失效。我们要查询在当前还没有失效的所有元素里面谁的价值最高。自然,如果一个元素加入的时间早(更有可能失效),其价值还赶不上后加入的元素,它便没有存在的必要。
本质:内部的元素从栈底到栈顶,价值越来越小,但是时效性越来越强。
应用:DP的优化。
 
例题:
T1.铁轨
(我在洛谷上找不到这题)
某城市有一个火车站,有n节车厢从A方向驶入车站,按进站顺序编号1~n。火车站只有一个入口,最外面的列车可以驶向B方向。你的任务是判断,一个输入的出站顺序,是否可能是合法的。(所谓合法指存在一种操作车厢的方法,可以得到该出栈顺序。如5 4 1 2 3是不合法的,5 4 3 2 1是合法的)
可以把火车站抽象为一个「栈」。由出栈序列倒推并和入栈序列比较。下一个出栈的车厢序号要么比已出栈的任何一节车厢的序号都大,要么比刚出栈的车厢序号小,才能满足题意。所以我们模拟这个过程,初始火车站是空栈,每次入栈,都与出栈序列进行比对,若相同则将栈顶弹出,不相同则再进一辆。用两个指针i,j分别表示当前第i节车厢已经进站,当前出站序列里面的第j节车厢已经出站。每次如果发现出站序列里面下一个要出站的车厢为当前栈顶的车厢,则让其出站,更新指针j。如果不是,则继续令后面的车厢进站,更新指针i。如果所有车厢已经进站了,但出栈序列没有完成(有车厢滞留了),则所给的出栈序列不是合法的。反之则合法。
 
 
T2.等价表达式
luoguP1054。
关于a的表达式变化无常,我们无法对其进行合并同类项。可以考虑特殊值法,但最好不要使用0,1,-1这样的数,这会导致冲突。可以代一些质数去判断两个表达式是否相等。而且要多代几个,也是为了降低冲突产生的概率。(数值法解决问题)
考虑到数据量极大,可能会爆long long。然而这道题使用高精度显然是不现实的,那么怎么办呢?我们考虑计算的时候去模一个你喜欢的质数 ,这样就好很多了。
具体实现方法:双栈。一个是数字栈,一个是符号栈。读入过程比较麻烦,建议寻找网上 题解参考。每当读入数字时压入数字栈,读入符号时要判断。如果是运算符,当前栈顶的运算符优先级大于等于新运算符,则将栈顶运算符弹出,并将当前数字栈顶的两个数进行相应运算,弹出旧数,压入新结果。不停循环,直到栈里面没有符号或符号优先级低于当前新运算符。如果是(,直接压入栈。如果是),则依次将栈里面的符号弹出,并计算。直到遇到一个(。
其实计算方法可以参照一道中缀表达式求值的问题,可以去网上搜一下。
小技巧:可以在表达式开头和结尾分别加一个括号,避免边界的特殊处理。
 
T3.全排列
全排列大部分情况下都是人工dfs或者algorithm头文件下的next_permutation来实现的。用栈也可以实现,但是几乎没多少人用。基于实用主义的角度,这里不再叙述。
 
 
2. 队列
队列也是一种运算受限的线性表。特殊之处在于它的查询和删除操作在队头,而插入操作在队尾(就像日常打饭排队那样)。
队列满足先进先出的特性。(明明是我先来的我应该先出去
队列广泛应用于各种BFS。
实现:实现:STL or 手写(请参照一本通 or 课件)
一般操作:判断队列空/满、入队、出队,判断队列的大小(请参照一本通 or 课件)
 
2.1 循环队列
一般手写队列存在空间浪费现象,对队首元素进行弹出操作之后,这块内存将无法再次被利用。在一些对于内存要求比较紧张的题目中,可以考虑使用循环队列。
(STL的一般队列就是循环队列,速度的话肯定要比手写慢一点,但是方便啊是不是)
(其实实际上没多少人用
当我们的队首或者队尾指针变成队列大小的最大值的时候,将其对这个最大值取模变为0。这样就实现了让队列首尾相接,不断循环。(具体代码可以去看数据结构基础班的课件)
2.2 双端队列(deque)
顾名思义,这样的队列支持在两端进行插入和删除操作。仅需在手写一般队列的代码上稍加改进即可。但是,千万不要用STL里的deque,那玩意慢的要死。所以如果你真的遇到一道题非得要双端队列做不可,那就老老实实的手写吧。。。
2.3 单调队列
定义类似单调栈。
 
例题:
T1.课程学习(?)拓扑序列
(我在luogu上找不到这题)
给定一张有向无环图(DAG),来描述某大学之间课程的联系。如果A到B有一条边,说明在学习课程B之前,必须要学习课程A。请找到一条合法的学习课程的序列,满足题目要求。所谓一张有向无环图(DAG)的拓扑序列,即为一个点的序列,满足对任意一条边(u,v),u都出现在v的前面。其实说白点,这个拓扑序列就是说按照一个从小到大的顺序把边排下序,保证前边的点一定要在后边的点的前面 。。。呃这样说可能比较抽象,如果感到理解困难就去看看课件吧。。
拓扑排序是一种类似BFS的方法。对于这个题来说,既然我们前边的点一定要在后边的点的前面,那么我们要找的第一个节点应该是入度为0的点,我们就枚举每个点,如果入度为0就放入队列中。顺序是无所谓的,拓扑排序大多情况下结果是不唯一的。然后我们取出队首节点进行扩展,将所有连接到的点入度-1.为什么不直接放入队列呢?因为可能有一些点有很多其他点相连,也就是有些课程需要的先修课不止一节。遍历完后把所有入度被更新为0的节点放入队列。继续过程直到队列空。在取出队首节点时输出这个节点,那么算法执行完毕后输出的结果就是拓扑排序的结果。
 
 

夏令营讲课内容整理Day 1.的更多相关文章

  1. 夏令营讲课内容整理 Day 7.

    Day7是夏令营的最后一天,这一天主要讲了骗分技巧和往年经典的一些NOIP试题以及比赛策略. 这天有个小插曲,上午的day7T3是一道和树有关的题,我是想破脑袋也想不出来,正解写不出来就写暴力吧,暴力 ...

  2. 夏令营讲课内容整理 Day 3.

    本日主要内容是树与图.   1.树 树的性质 树的遍历 树的LCA 树上前缀和   树的基本性质: 对于一棵有n个节点的树,必定有n-1条边.任意两个点之间的路径是唯一确定的.   回到题目上,如果题 ...

  3. 夏令营讲课内容整理Day 0.

    今年没有发纸质讲义是最气的.还好我留了点课件. 第一次用这个估计也不怎么会用,但尝试一下新事物总是好的. 前四天gty哥哥讲的内容和去年差不多,后三天zhn大佬讲的内容有点难,努力去理解吧. 毕竟知识 ...

  4. 夏令营讲课内容整理 Day 6 Part 3.

    第三部分主要讲的是倍增思想及其应用. 在Day3的整理中,我简要提到了倍增思想,我们来回顾一下. 倍增是根据已经得到的信息,将考虑的范围扩大一倍,从而加速操作的一种思想,它在变化规则相同的情况下,加速 ...

  5. 夏令营讲课内容整理 Day 6 Part 2.

    Day 6的第二部分,数论 数论是纯粹数学的分支之一,主要研究整数的性质   1.一些符号: a mod b 代表a除以b得到的余数 a|b a是b的约数 floor(x) 代表x的下取整,即小于等于 ...

  6. 夏令营讲课内容整理 Day 6 Part 1.

    Day6讲了三个大部分的内容. 1.STL 2.初等数论 3.倍增   Part1主要与STL有关. 1.概述 STL的英文全名叫Standard Template Library,翻译成中文就叫标准 ...

  7. 夏令营讲课内容整理 Day 5.

    DP专场.. 动态规划是运筹学的一个分支, 求解决策过程最优化的数学方法. 我们一般把动态规划简称为DP(Dynamic Programming)   1.动态规划的背包问题 有一个容量为m的背包,有 ...

  8. 夏令营讲课内容整理 Day 4.

    本日主要内容就是搜索(打暴力 搜索可以说是OIer必会的算法,同时也是OI系列赛事常考的算法之一. 有很多的题目都可以通过暴力搜索拿到部分分,而在暴力搜索的基础上再加一些剪枝优化, 就有可能会拿到更多 ...

  9. 夏令营讲课内容整理 Day 2.

    本日主要内容是并查集和堆. 并查集 并查集是一种树型的数据结构,通常用来处理不同集合间的元素之间的合并与查找问题.一个并查集支持三个基本功能:合并.查找和判断.举一个通俗的例子,我和lhz认识,lhz ...

随机推荐

  1. dijk

    .....................用矩阵存..................... 1 int mp[N][N]; bool p[N]; int dist[N]; void dijk(int ...

  2. find the nth digit(二分查找)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1597 find the nth digit Time Limit: 1000/1000 MS (Jav ...

  3. list容器的C++代码实现

    #include <iostream> using namespace std; template  <class T> class mylist;//前置声明 templat ...

  4. 久未更 ~ 三之 —— CardView简单记录

    > > > > > 久未更 系列一:CardView 点击涟漪效果实现 //在 cardview 中 实现点击涟漪效果 android:clickable="t ...

  5. include指令与include动作的区别(面试要考)

    include指令: 语法格式:<%@ include file=" " ...%> 发生作用的时间:页面转换期间 包含的内容:页面的实际内容 转换成的servlet: ...

  6. Navicat如何进行搜索筛选

    分类: Navicat Navicat提供的"在数据库或模式中查找"功能用于一个数据库和/或模式内搜索表和视图的记录.Navicat"对象筛选"功能可以让用户在 ...

  7. JavaScript之事件委托(附原生js和jQuery代码)

    事件委托的原理依赖于事件冒泡,可以通过给父元素的事件委托来确定是哪个子元素触发了事件从而做一系列操作. 使用事件委托的优点 1.操作子元素时不用一一遍历,可以根据事件触发的对象而进行相应操作 dom结 ...

  8. 【开发技术】Java生成验证码

    Java生成验证码 为了防止用户恶意,或者使用软件外挂提交一些内容,就得用验证码来阻止,虽然这个会影响用户体验,但为了避免一些问题很多网站都使用了验证码;今天下午参考文档弄了一个验证码,这里分享一下; ...

  9. struts异常:Caused by: Parent package is not defined: json-default - [unknown location]解决办法

    问题描述: Unable to load configuration. - [unknown location] at com.opensymphony.xwork2.config.Configura ...

  10. JavaScript对象的valueOf()方法

    js对象中的valueOf()方法和toString()方法非常类似,但是,当需要返回对象的原始值而非字符串的时候才调用它,尤其是转换为数字的时候.如果在需要使用原始值的上下文中使用了对象,JavaS ...