第七周ACM博客总结

这一周呢,自己主要是做题了,而且做题的时候有的也是先看博客再去做题,所以满打满算,这一周看的篇数基本足够。这一周自己明显感觉对题目的思考更深入了,一个题目能总结出好多知识,而且AC的题目也比上周多了,但是也得多加练习,很多题目也是得先看博客才能求解。下面是这一周的具体总结,一共两部分,题目理解,以及反思和规划。

一、搜索题目深度总结

(一)DFS深度理解

1、城堡问题----数学建模、转化为图(DFS)

今天自己看到了一个挺典型的题目,城堡问题,这类问题可以不断增加条件来增加题目的难度。具体题意就是给出一个城堡的地形图,算出有多少房间,最大的房间有多大,每个方块周围有墙,联通在一块的算做一个房间。解这个题呢,得需要用到建模的思想,就是把每个房间看成是一个结点,房间与房间之间的联通与不连通看成是一条线,这样整个题目就通过建模的思想转化成了一张图的模型,这样复杂问题变得具体化、简单化,就容易理解和处理了。核心思路还是深搜,这里还可以换一种想法,可以用涂颜色来模拟这个搜索的过程,就是说,到达一个地点就涂上相应的颜色,最后就可以统计出有几种颜色,每种染色的数量,分别对应房间数和房间的面积。具体步骤呢,就是要先定义矩阵,并且定义二维数组判断是否染过颜色。写出DFS的递归函数即可。

通过这个题呢,有一个困扰我很久的疑问终于解开了,我一直不明白只写个return是什么意思,而且自己也想象不出到底是个什么样的框架。现在我终于明白了,意思就是说,就比如说到了一个岔路口,有很多条路可以走,就比如说有4条路吧,走了1号路,发现是个死胡同,可以写个return,直接返回,表示这条路走不通,就不用再走了,直接就停止了,再走其他路就可以了。因为之前从来没这样写过,所以自己一上来就有点不大理解,不过好在终于明白了。

还有一个方向数组的问题,自己无论是看课本还是看资料,那些博主们基本都会定义方向数组,虽然说这样写非常简练而且很高级巧妙。但是自己呢,也更希望首先以一个先能更好理解的方式来写代码,然后再慢慢的过渡到像那些高手的的写法。像下图这样(手敲),适当改写DFS函数,并且4个方向我都写一遍,这样虽然繁琐,但是自己很容易理解,一看就懂,当然了,自己也会慢慢过渡提高的。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5pqX57Sr6Imy55qE5LmU5p2-KC1fXik=,size_14,color_FFFFFF,t_70,g_se,x_16

 而且自己也在尝试用memset(color,0,sizeof(color));来赋初值,这样写真的很方便,非常简练易懂。

2、踩方格问题(DFS)

题目背景呢还是一个矩阵,给定一个固定的步数,问在矩阵上走可以有多少种不同的方案。这个题把代码写出来时间复杂度挺高的,核心思路还是DFS,由于题目没给一个固定的起点,所以我们可以选择一个好的最优起点来解决这个问题。大体的思路就是,从(i,j)出发,走n步的方案数,结果呢就等于分别从(i+1,j),(i,j+1),(i,j-1)出发的方案数之和,要注意这些点还没有走过。需要注意的是,走到剩余步数为零时,就要return结束道路了,还有就是visite[i][j]一开始是1,记得后边要把它变成0,因为题目要求只要有一步不一样,就可以算作一种方案,所以呢,一条路径访问过了,最后一定要设置成没有访问过,让其他路径也要能访问到这个结点,如下图所示(手敲)。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5pqX57Sr6Imy55qE5LmU5p2-KC1fXik=,size_11,color_FFFFFF,t_70,g_se,x_16

3、八皇后Checker Challenge----回溯(DFS)

终于做到八皇后的问题了,之前很好奇八皇后到底是个什么题目,名字都起的这么吸引人。题意呢是说有n乘n的一个棋盘,每行每列只能放一个棋子,求所有放置方式。非常经典的一个DFS问题,为了表示要占据相应的位置,要单独设立4个数组,行,列,左斜,右斜。需要知道的是,右斜坐标的特点是是y-x等于一个定值,但是可能为负,所以要加上n,代表一个平移的操作吧。左斜坐标x+y是一个定值,不可能为负值,所以左斜可以写成ls[k+i],右斜可以写成rs[k-i+n]。在递归中注意回溯操作,不要影响下一个路径的判断。目前还是对整个过程有点想象不出来,特别是在循环中既递归又回溯的,有时候就有点转不过来,还是得多加理解。

不过还是要记录一下这个典型题目!

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5pqX57Sr6Imy55qE5LmU5p2-KC1fXik=,size_20,color_FFFFFF,t_70,g_se,x_16

4、高手去散步----图论、回溯(DFS)

这个题呢是说,有n个景点,m条游步道,景点之间有不同距离,求解最长路径。这个题呢,自己是看了题解之后才明白了那么一点点。这个题和其他题目的一个典型区别是,要像下面这样需要定义一个双向图。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5pqX57Sr6Imy55qE5LmU5p2-KC1fXik=,size_9,color_FFFFFF,t_70,g_se,x_16

除此之外,这个题的关键在于要注意标记和清零,不能影响下一条路径的搜索,核心的还是利用DFS递归函数及时的更新数据。

5、填涂颜色(DFS)

题目背景呢还是一个矩阵,里边有一个闭合圈,要求把闭合圈"涂成一样的颜色",闭合圈全是1,其余的地方全是零,要把闭合圈内的零涂成2,其余的不变。一开始自己想这个题,大体的框架自己可以写出来,唯一困扰自己的地方就是如何把里边那个闭合圈找出来,而且不会触碰到闭合圈之外的,第一次自己是直接用DFS找的,没有把这一部分的代码写进去,结果一提交,的确没有通过。然后我就换了一种思路,可以从边界处开始寻找为零的数,把它们做好标记,只要把这一部分找出来了,就很好处理了。最后再遍历整个矩阵,刚才标记过的涂上一种颜色,闭合圈内的涂上一种颜色,其余的地方涂上一种颜色,将整个矩阵涂完颜色之后,输出就可以。总之,这个题的核心在于如何把这几个部分给分隔开再涂颜色,可以用如下写法(手敲),遍历边界处的零,并且把与之相连的0也做好标记,这样就把闭合圈外的零和闭合圈内的零区分开了,顺利解决。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5pqX57Sr6Imy55qE5LmU5p2-KC1fXik=,size_10,color_FFFFFF,t_70,g_se,x_16

 

(二)BFS深度理解

 6、封锁阳光大学----二分染色、二分图(BFS)

这个题目感觉挺有意思的,一开始我都没看出来是DFS还是BFS,但是感觉还是用BFS来解决。题意是说给定n个结点和m个边,让把结点封锁住,使得结点之间不能联通,但相邻结点不能同时封锁。这个题也很像一个染色的题目,可能还用到了点图的知识。这个题理解起来有点困难,看了好几遍题解都没看懂,看了大佬的写法,才了解到这个题目好像用到了二分图,结合染色法出的一道题目。转载一下大佬的代码,queue和vector都用上了。整体思路呢,就是先把一个点染色,相邻的点跟它用不同的颜色,如果相邻点的颜色相同,这就不是二分图,如果是二分图的话,在每次染色时统计黑点和白点个数,最后两个比较,统计出那个较小的就可以了。这个题自己以后还是要多加理解才能彻底明白。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5pqX57Sr6Imy55qE5LmU5p2-KC1fXik=,size_20,color_FFFFFF,t_70,g_se,x_16

 7、血色先锋队----多起点多终点(BFS)

这个问题自己感觉特别新颖,因为之前做的都是一个起点的问题,一般也只有一个终点。但是这个题目呢多起点,多终点问题,自己写了好久才通过。题意呢,就是说有多个感染源,有多个领主,求感染源传染每个领主的时间。核心思路呢,就是先要初始化每个位置都为同一个默认值,然后循环让每个传染源向四周扩散,扩散一步标记为1,扩散两步就标记为2,以此类推,标记过的不再访问,这样就保证了到达每一个领主的时间都是最短的。经过这样一番操作,很像涂颜色的问题,最后整个矩阵都被涂成了相应的步数,最后只将领主所在位置的数字输出就是感染的时间,主要还是队列这种先进先出的模式使得可以求出最小的时间。浅浅记录一下AC过程。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5pqX57Sr6Imy55qE5LmU5p2-KC1fXik=,size_20,color_FFFFFF,t_70,g_se,x_16

8、马的遍历(BFS)

这个题目比一般的BFS复杂了些,因为要定义8个方向,每个点都要遍历到。题意就是在一个矩阵中给定马的坐标,求到达各点的最小步数。思路呢,和那个血色先锋队差不多一致,基本思路还是将矩阵全都设置成默认值,然后利用队列的这种性质,遍历整个矩阵,这样每个位置都被标上了相应的数字,最后输出整个矩阵即可,第一次提交发现没有提交成功,主要是最后的输出格式不对,最后还是用了C语言中的printf控制输出才顺利AC的。突然发现这个题也好像涂颜色的问题,这里就不再多做总结了。

 

二、自我反思与规划

自己看的这些题目有相当一大部分都会用到"涂颜色"思想,这应该是一个基础内容,很多题目都会以这个为基础进行变形,并且和其它算法知识结合出题。看的博客当中也有一些新的题型, 比如说是八数码问题魔方还原问题翻转游戏双层BFS问题三维BFS问题等,这些新题型感觉难度都挺大,大佬们写的代码真的也很难懂。

总之吧,这一周是做题较多的一周,也是理解较为深刻的一周,一些基本的题目,或者说是变形的题目也都差不多见识了。自己也能下手写出代码了,就算没有全写出来,大体的思路也都是没错的,再结合博客进行完善,就会对这些题型的具体解法有了很好的了解。感觉AC一道题目还是挺困难的,因为有了思路还不行,得把它写出来才是主要的,写出来了还不够,输出结果还不一定规范呢,下次遇到类似的,能独立把它写出来吗,这些都是要考虑的,还是得多加练习才行呀。

下周,自己计划还是每天坚持做题,闲暇时看几篇博客,避免任务都压到最后才去做,一切都有计划有条理的进行下去就可以了。

好啦,这就是第七周的全部总结了,下周保持良好的状态继续前行,自己会不忘自己的初心,并且在学习算法这条道路上一直走下去!

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

暗紫色的乔松(-_^)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值