主要内容是栈和队列。

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. c#版 K线控件(Stock)

    K线起源于日本米市交易,它的基本用途就是为了寻找"买卖点".股市及期货市场中的K线图的画法包含四个数据,即开盘价.最高价.最低价.收盘价,所有的k线都是围绕这四个数据展开,反映大势 ...

  2. c++中的overload、overwrite、override

    作为初学者,本文只从语法和简单的使用角度对overload.overwrite.override进行了区分,不曾涉及原理,记录下来以供查阅. 1.verload(重载) 1.1 基本要求: c++中的 ...

  3. Tomcat学习笔记(二)—— 一个简单的Servlet容器

    1.简介:Servlet编程是通过javax.Servlet和javax.servlet.http这两个包的类和接口实现的,其中javax.servlet.Servlet接口至关重要,所有的Servl ...

  4. UE4 小笔记

    1,设置postprocess材质时使用Add or Update Blendable 用Make PostprocessSetting会报警告,因为C++代码中没有设置为BlueprintReadW ...

  5. 实例说明optimize table在优化MySQL时很重要

    今天在看CU的时候,发现有人问有关optimize来表优化的问题,当年因为这个问题,困扰我很长一段时间,今天有空我把这个问题,用实际数据来展示出来,让大家可以亲眼来看看,optimize table的 ...

  6. 安装Wamp后 Apache无法启动的解决方法

    安装Wamp后 Apache无法启动的解决方法,网上的解决方案可以说是五花八门,有些说了一大推,一点作用都起不到. 其实解决方法只需两步: 1.安装路径不能包含有中文,这个我不知道为什么,总之如果安装 ...

  7. 虚拟主机、VPS以及云主机的区别和对比

    对于很多需要建网站的朋友来说,虚拟主机是必须要了解的基础知识.虚拟主机相对于VPS与云主机来说出现的较早,也是被大多数站长所了解的主机.很多人容易将这三者混淆,弄不清楚三者的联系与区别.那么虚拟主机. ...

  8. Python3 的元组

    元组(tuple):戴上了枷锁的列表 元组与列表非常相似但是元组内元素的类型相同,且元组内的元素不能修改 1.创建元组的方法 与列表不同创建元组大部分情况下是用小括号,例如 tuple1=(1,2,3 ...

  9. RAC和单节点数据库的区别有哪些?RAC最有用的功能是什么?

    区别 (1)RAC有2个以上的实例,单节点只有1个实例 (2)RAC具有实例级别的高可用 (3)实例与实例之间通过内联网络交换数据,单节点不可 (4)RAC每个节点都有自己套SGA.后台进程.redo ...

  10. socket 编程--sockaddr与sockaddr_in区别与联系(转)

    在linux环境下,结构体struct sockaddr在/usr/include/linux/socket.h中定义,具体如下:typedef unsigned short sa_family_t; ...