算法笔记#4:深搜(DFS)
写在最前:
粉丝快要破百了,非常感谢大家的支持。每次在撰稿的时候,都感觉自己站在舞台的中央,都感觉台下始终有人在期待着我的表现,这种感觉,从小到大算是很少有了。。
2022年12月3号,离这一年结束,也就只有二十来天了。作者不算是什么特别强的人,只是一个经历了高考的失利,去了一个不知名的大学,和周围的人一样普通的大一新生罢了。写文章的初衷是想在生活中找一个让我能够去坚持的事情,顺便记录一下学习的过程,给前进路上的每一个脚印存一个档。我制作了一个算法笔记更新的日程表,以后坚持一周至少发一篇,争取两篇。经历了高考的挫折之后,应该深刻的认识到什么叫患得患失。大学四年,哪怕是坚持去追一个女孩,都比漫无目的、四处乱撞、最后原地踏步来的好。
以上只是个人想法,不多说了。深搜部分也准备分两篇发。
题目均来自TZOJ。
何为搜索算法?
搜索实质上是树的应用。初始状态对应着根节点,目标状态对应着目标节点。排在前面(上一级)的节点叫做父节点,其后的点叫做子节点,同一层中的节点是兄弟节点,由父节点产生子节点的过程叫扩展。完成搜索的过程就是找到一条从根节点到目标节点的路径,找出一个最优的解。
深搜(BFS):
深搜的基本思想是:为了求得问题的解,先选择某一种可能情况向子节点进行探索,在探索过程中,一旦发现原来的选择不符合要求,就回溯到父节点重新选择另一节点,继续向前搜索(在分岔口选错了路,沿着错误的路走到头以后意识到了,再原路返回至分岔口,选择另外一条路重复上述过程)。如此反复进行,直至求得最优解。一般深搜的过程要使用递归来实现。
深搜的过程中还有一个重要的步骤是回溯。回溯一般就需要对走过的路径进行标记。具体操作看代码。
先来看两道类似的看地图找人类(我自己起的名字)题目
玉树搜救行动
描述
自从玉树受灾以来,有关部门一直在现场抢救落难的人。他们用个种方法搜救,用上了搜救犬,有了搜救犬找到生命迹象就容易了。
假设现场用一个矩阵表示,抢救的有多条搜救犬,受灾的人也有多个可能。
例子:
#p.d#p#
#####.#
d……..#
######p
d表示搜救狗,p表示受灾的人,点表示可以通行的路,#表示石头挡住的路,不能通行。
搜救狗只能上下左右走,不能越过障碍物。
上面的那个例子最多可以救到2个人。因为第三个人被四周包围搜救狗无法到达。
输入
输入数据有多组。每组两个整数R,C, 2= 输出 输出搜救狗最多能救多少受灾的人的数量。 样例输入 4 7 样例输出 2 从数组的第一个元素开始搜索,如果遇到了边界或者遇到“#”号则不再递归直接返回。 把找到人的节点标记修改为“#”,下一次遍历的过程中就可以直接跳过了。 counting sheep 描述 A while ago I had trouble sleeping. I used to lie awake, staring at the ceiling, for hours and hours. Then one day my grandmother suggested I tried counting sheep after I'd gone to bed. As always when my grandmother suggests things, I decided to try it out. The only problem was, there were no sheep around to be counted when I went to bed. 输入 The first line of input contains a single number T, the number of test cases to follow. 输出 For each test case, output a line containing a single number, the amount of sheep flock son that grid according to the rules stated in the problem description. 样例输入 2 样例输出 6 3 "#"代表sheep,“.”代表grass,题目意思就是说如果羊是成群的,互相紧贴的,算一只,单个的羊也算一只。按照第一个例子来说,那五个挨在一起的羊就算作一只,再加上五个落单的,因此一共有6只。过程和上面的差不多。 八皇后问题 描述 在国际象棋棋盘上放置八个皇后,要求每两个皇后之间不能直接吃掉对方。 输入 无 输出 按给定顺序和格式输出所有八皇后问题的解(见样例,要求按照列优先的顺序输出各个解)。 样例输入 样例输出 No. 1 这是一道,深搜回溯递归结合的经典题。具体做法也是我上网课学来的。 八皇后的基本规则如下:在一个8*8的棋盘中放置8个皇后,要求每一横列,竖列,斜列只有一个皇后。那么当第col列被占领后同一列都不能再放置皇后,那么就需要把第c列设置为占领状态。这里比较麻烦的是对角线,有上下对角线之分。当第一个位置被皇后占领后,上下对角线都要设置为被占领状态。在这里1代表占领,0代表未占领。递归终止的条件是,皇后又地方可以放,或者皇后在全部遍历完了还是没地方放。 在递归之后要进行回溯。吧所有的数据都初始化,从头再来以寻找最多的可行放法。 我在代码后面写了注释,希望大家能看懂。 未完待续 欢迎私信,评论区交流!
#p.d#p#
#####.#
d.....#
######p
0 0#include
Creative as I am, that wasn't going to stop me. I sat down and wrote a computer program that made a grid of characters, where # represents a sheep, while . is grass (or whatever you like, just not sheep). To make the counting a little more interesting, I also decided I wanted to count flocks of sheep instead of single sheep. Two sheep are in the same flock if they share a common side (up, down, right or left). Also, if sheep A is in the same flock as sheep B, and sheep B is in the same flock as sheep C, then sheeps A and C are in the same flock.
Now, I've got a new problem. Though counting these sheep actually helps me fall asleep, I find that it is extremely boring. To solve this, I've decided I need another computer program that does the counting for me. Then I'll be able to just start both these programs before I go to bed, and I'll sleep tight until the morning without any disturbances. I need you to write this program for me.
Each test case begins with a line containing two numbers, H and W, the height and width of the sheep grid. Then follows H lines, each containing W characters (either # or .), describing that part of the grid.
Notes and Constraints
0 < T <= 100
0 < H,W <= 100
4 4
#.#.
.#.#
#.##
.#.#
3 5
###.#
..#..
#.####include
1 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0
0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1
0 1 0 0 0 0 0 0
0 0 0 1 0 0 0 0
0 0 0 0 0 1 0 0
0 0 1 0 0 0 0 0
No. 2
1 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0
0 0 0 1 0 0 0 0
0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 1
0 1 0 0 0 0 0 0
0 0 0 0 1 0 0 0
0 0 1 0 0 0 0 0
......#include
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
