基础巩固2训练小结

本周的基础巩固2训练了基础数据结构:队列,链表,树,图,以及DFS和BFS算法等。下面总结一下一些需要注意的地方。

数据结构结构基础中树是一个难点,因为树的定义就是递归的,因此解决和树有关的问题总是从递归的思想上去考虑。树的结构中最常见的是二叉树,二叉树自身有很多独特的数学特性,因此题目中经常见到这种树,比如本次训练的E题,利用的就是二叉树叶子结点i的深度depth与总结点数的关系:1<<depth。另一个经常见到的就是四分树,在处理黑白图像类的题目中经常会遇到。树的最基本的遍历方式有三种:先序遍历,中序遍历和后序遍历。不过需要注意的是:不论采用哪一种遍历,思路都是相同的:先解决边界问题——遍历到叶子结点时,处理完及时返回,然后再递归处理左子结点和右子结点。对于四分树,处理方法类似。另外,经常遇到的一种题型是从遍历的序列中构造出来原来的树。比如本次训练的F题,就是要求将四分树转换为十进制序列和十进制序列构造出四分树。


数据结构中的图涉及了第一次学习时不常遇见的内容:拓扑排序和欧拉回路。本次训练的B题就是一道典型的用欧拉道路解决的问题。关于欧拉道路,要根据结论来编程解决:对于无向图,度数为奇数的结点不能超过2个;如果有2个,那么其中一个的入度比出度小1,另一个的入度比出度大1。因此解决这类问题时要从结点的度数取考虑。比如这次训练的I题,需要找到一条路径,必须包含指定的m条路径。如果试图去构造一条符合题意的道路肯定是比较麻烦的,应当先判断指定的m条路径中有多少个连通分量,统计这些连通分量中度数为奇数的点,只需要将它们额外扩展一条路径即可,考虑到对称性和出入结点的度数为奇数,最后总结出需要增加的路径数是E+(res-2)/2。拓扑排序的一个重要作用是判断有向图中是否含有有向环,本次训练的C题,要求判断给定的n种正方形能否组成一个无限大的结构。通过观察我们会发现,如果可以的话,其中必然有一些正方形要循环出现,以往内给定的正方形种类是有限多的。而正方形的重复出现意味着连接点的重复出现,意味着连接点构成了一个有向环。这样就将一个看似复杂的,无从下手的问题转变为了简单的拓扑排序问题。


关于DFS,它经常用于搜索连通块。本次训练的A题是一道非常好的联系DFS的题目,给了你6种埃及象形符号的编码后的图片,让你找出其中包含了哪些象形符号。一方面需要观察出这6中符号各自独有的特征,即他们包含的洞的个数是不同的。然后就是利用DFS来找洞的个数。不过要注意先处理边界,就像剪贴画一样,先把周围的轮廓勾勒出来,然后再精加工,即寻找每个符号中洞的个数。在写DFS的代码时,要注意这些问题:首先先处理递归边界,及时返回非法的情况,然后标记该结点,防止重复访问,最后利用向量数组向外围递归扩展。如果一道题中需要多种DFS,可以考虑添加一个控制参数isp,便于针对不同的情况进行不同的处理,简化代码。DFS的作用是简单的,但要学会灵活运用,对于“连通块”的选取要根据情况而转移,比如本次训练的D题就是这样的一道题,一个正方形中有若干个圆形障碍物,问你是否存在从正方形左边界到达正方形右边界的一条通路,如果有,输出最靠北边的入口和出口。如果我们把正方形中除去圆的部分看做待搜索的连通块,显然我们会遇到一个大问题:边界不好处理,因为圆有很多,你很难确定这一点进入了哪个圆的范围内。加入我们换个角度考虑,把圆看待搜索的连通块对象,那么问题就会大大简化,如果从上边界可以和下边界连通,那么必然不存在合法的路径。而圆向外扩展只需要判断这n个圆中,哪些与当前的圆相切或相交即可。


关于BFS,它经常用于图的最短路问题,最典型的一类问题就是迷宫路径搜索问题。不过这类题目中经常会添加许多形形色色的限制条件,你需要按照给定的条件来一步步走,最终从入口走到出口。对于这类题,首先要明确“状态”,最简单的状态就是当前的坐标了。复杂一点的状态经常要定义一个State结构体来解决。对于简单的状态,可以直接利用STL中的queue解决,对于八数码问题这种复杂的状态,定义完State结构体中,经常用模拟队列解决,即用front和rear来控制入队列和出队列。本次训练的G题:筛子难题就要这样来解决。关于BFS的写法需要注意这些问题:在出列时先判断是否到达了终点,否则继续扩展;及时标记当前路径的长度和父结点,同时用vis数组来标记当前状态已经访问过,避免重复访问,复杂一点的状态标记可能要用到hash技术。最后如果要打印路径,可以沿着父结点从终点返回起点,返回途中将结点放入vector中。这种做法需要从后往前输出路径;如果不想这样输出,可以利用把打印函数写成递归形式,递归结束后再将结点放入vector。


本次训练的这些数据结构是后面更高级的数据结构的基础,因此在往后训练中,还应当继续加强巩固。

你可能感兴趣的:(基础巩固2训练小结)