基础巩固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。

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

时间: 2024-07-30 14:40:05

基础巩固2训练小结的相关文章

小菜汇编基础和学习技巧小结(一)

以下小结纯属小菜自学过程产生的dump,大神请飘过! 汇编是一门庞大复杂的学问,在计算机的世界里差不多无所不入.很多编程领域都会或多或少跟汇编打交道.本人不是科班出身的程序员,所以很多基础都为零,学历也很低.因此学习汇编的难度可想而知.不过还是凭自己的耐力,掌握了少许的知识.下面做个小小的总结,分享给和我一样想入门汇编的朋友们. 1.参数直接传值和传入数值变量的区别 void SetX(int x) { x = 6; } int _tmain(int argc, _TCHAR* argv[])

模拟专题训练小结

本周我进行了针对模拟题的训练,在比赛中,模拟题是考察一个人代码综合能力的最佳体现,也是考验选手对细节的把握能力的有力工具.本周的模拟题大多来自WF和Regional,而前者的模拟题一般细节比较多,编程比较复杂.下面来根据我本周的训练情况来简要总结一下这方面需要注意的地方. 首先,应该完全理解题意,这一步相当关键,如果连题意都理解错了,那么后面无论花多大功夫去调试代码都是无济于事,因为你一直在实现一个错误的模拟过程.弄明白题目的全部流程,接下来就是考虑顶层设计:有哪些全局变量,需要设计哪些结构体,

JavaScript服务器端开发基础之Math对象小结

JavaScript提供基础的算术运算符来实现对算术运算的支持,例如加法运算符+,减法运算符-,乘法运算符*,除法运算符/和求余运算符%.此外,还支持复杂的算术运算,这是通过作为Math对象的属性定义的函数和常量来实现的. 使用 Math 的属性和方法的语法如下所示: var pi_value=Math.PI; var sqrt_value=Math.sqrt(15); 注释:Math 对象并不像 Date 和 String 那样是对象的类,因此没有构造函数 Math(),像 Math.sin(

java基础集合经典训练题

第一题:要求产生10个随机的字符串,每一个字符串互相不重复,每一个字符串中组成的字符(a-zA-Z0-9)也不相同,每个字符串长度为10; 分析:*1.看到这个题目,或许你脑海中会想到很多方法,比如判断生成的字符串是否包含重复,在判断长度是不是10,等等. *2.其实这题我们可以培养一个习惯,大问题分解小问题解决. (1).10个字符串,我们先产生一个10个字符不重复的字符串,   (2).怎么去重复呢?集合中的HashSet就可以,这题不适合用包含方法做,代码复杂   (3).字符组成是由(a

Linux基础--入门常遇问题小结

系统环境  Ubuntu 14.04 server amd64 刚刚学习Linux,遇到了很多问题,下面总结一下. 在刚刚安装完成的Linux系统中,有很多程序是没有安装的.例如vim tree等等. 1.使用vi时,为什么跟老师讲的不一样?为什么使用方向键时会输入字母D.C等,而不是上下换行? 在没有安装vim前,使用vi,用的是老版的vi.用vi打开文件,在里面使用输入模式,屏幕坐下并没有--insert--这个标志,使用backspace键也并不能直接删除命令,与新版的vim有很大的不同,

机器学习基础:(Python)训练集测试集分割与交叉验证

在上一篇关于Python中的线性回归的文章之后,我想再写一篇关于训练测试分割和交叉验证的文章.在数据科学和数据分析领域中,这两个概念经常被用作防止或最小化过度拟合的工具.我会解释当使用统计模型时,通常将模型拟合在训练集上,以便对未被训练的数据进行预测. 在统计学和机器学习领域中,我们通常把数据分成两个子集:训练数据和测试数据,并且把模型拟合到训练数据上,以便对测试数据进行预测.当做到这一点时,可能会发生两种情况:模型的过度拟合或欠拟合.我们不希望出现这两种情况,因为这会影响模型的可预测性.我们有

【Java基础】Java多线程小结

在说多线程之前,首先要清楚为啥要提出多线程,这就要明白线程和进程间的区别了. 线程和进程间的区别 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位. 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源. 一个线程可以创建和撤销另一个线程,同一个进程中

前端工程师养成手册——基础学习——第一周小结

第五章关键点总结 数组与集合的对比 1.都是用来保存多个同类型的数据,数组具有定长性,而集合不具有定长性,因此保存数量固定的数据时可以用数组,数量会发生变化的可以用集合: 2.数组建立后,每一项为该数据类型的默认值:而集合建立后,当中没有元素,因为长度为0: 3.数组分析器 代码: static void Main(string[] args)        {            int[] nums;            int len;            #region 创建数组 

ACM训练小结-柳志轩-2018年6月15日

今天题目情况如下:A题:给出若干条边的边长,问这些边按顺序能否组成一个凸多边形,并求出这个多边形的最小包含圆.答题情况:无思路.正解(某种):第一问很简单.对第二问,如果R大于可行的最小R,那么按照放在圆上的方法算出asin(li/2R)其和大于R,说明此R可以缩小.当然R也有最小值为Max(li)/2 B题:jenja游戏,介绍规则后问先手胜还是后手胜.正解:高度%3后等0后手胜,否则先手胜.这种题都有很明显的规律性.答题情况:找到规律顺利解除. C题:要求曼哈顿距离的快速迭代.正解:写出基本