蓝桥杯——2016B组真题第七题 剪邮票(全排列和dfs或bfs)一道题带你搞懂DFS和BFS_第七题 剪邮票 问题描述 如图,有 12 张连在一起的 12 生肖的邮票。 在这里插入图-CSDN博客

admin 1个月前 (04-07) 直播 27 0
蓝桥杯——2016B组真题第七题 剪邮票(全排列和dfs或bfs)一道题带你搞懂DFS和BFS_第七题 剪邮票 问题描述 如图,有 12 张连在一起的 12 生肖的邮票。 在这里插入图-CSDN博客

  题目描述

  如【图1.jpg】, 有12张连在一起的12生肖的邮票。

  现在你要从中剪下 5 张来,要求必须是连着的。

  (仅仅连接一个角不算相连) 比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。

  请你计算,一共有多少种不同的剪取方法。

  DFS思路:

  我是参考b站的Eric_Richard博主给的思路。由于要是想以某个格子作为起点,然后再依次去选取五个连接的格子的话,这种思路会需要把这多种情况记录起来再去去重,然后最后得出结果。所以我这道题选取了这个博主的思路,就是把全排列选取随机的五个点,然后再去判断这五个点是否是连通的。全排列可以用全排列函数(next_permutation()或prev_permutation(),具体用法也可以看我的另外一个blog:蓝桥杯——2013B组真题第九题 带分数)

  在《算法笔记》中可以了解到,“使用递归可以很好地实现DFS。这个说法并不是说深度优先搜索就是递归,只能说递归是深度优先搜索的一种实现方式,因为使用非递归也是可以实现DFS的思想的,但是一般情况下会比递归麻烦。不过,使用递归时,系统会调用一个叫系统栈的东西来存放递归中每一层的状态,因此使用递归来实现DFS的本质其实还是栈”。

  代码如下:

  BFS思路:

  跟DFS一样的思路,还是利用全排列随机选取5个点,然后通过BFS来判断每次所要剪的五个格子是否是连通的(即连着的)。跟DFS相比,多了一个判断元素是否已经入队的二维数组。

  参照《算法笔记》,广度优先搜索(BFS)一般由队列实现,且总是按层次的顺序进行遍历,其基本写法如下(可作模板用):

  代码如下:

  结果:

  116

  总结:

  DFS是通过从一个点一直往下走,直到遇到"死胡同"(即退出条件),才一点一点往后走,并加入下一个分岔口。BFS是通过一层一层的,从一个点的每一层出发,直到找到出口。(这里属于个人见解,要是觉得不对的,还请斧正!)

  在BFS中设置的inq数组的含义是判断结点是否已入过队,而不是结点是否已被访问过。区别在于:如果设置成是否已被访问,有可能在某个结点正在队列中(但还未访问)时由于其他结点可以到达它而将这个结点再次入队,导致很多结点反复入队,计算量大大增加。因此BFS中让每个结点只入队一次,故需要设置inq数组的含义为结点是否已入过队而非结点是否已被访问。

  最后指出,当使用STL的queue时,元素入队的push操作只是制造了该元素的一个副本入队,因此在入队后对原元素的修改不会影响队列中的副本,而对队列中副本的修改也不会改变原元素,需要注意由此可能引入的bug(一般由结构体产生)。

相关推荐

网友评论

  • (*)

最新评论