1.广度优先搜索
- 广度优先搜素自身具有求最值得特性,一般用于求最值问题,比如说最短路径等等。目前博主知道广度优先搜索的优化有双向广度优先搜索,迭代加深搜索等等。
2.广度优先搜索相关应用
-
地牢逃脱 :该题我们可以看到是求最值问题,因此我们考虑适用广度优先搜索,用队列实现,用pair<int,int>对数据进行包装。
-
最少计算次数 :这道题涉及到负数,而且计算量比较小,况且是求最小的情况,可以考虑广度优先搜素,当然也可以用动态规划。
-
图的遍历 :这道题要求最短路径,最值问题,况且题目是图,因此,可以考虑广度优先搜索。
-
目的地最短步数: 这道题求最短步数,属于最值问题,而且题目的数值没有明确大小的,意味着数值不会太大,因此,可以考虑广度优先搜索。同时,这道题的广度优先搜索存在一定的规律,因此我们可以根据规律去求解问题。
2.双向广度优先搜索
2.1 双向广度优先搜索背景
- 双向广度优先搜索顾名思义就是从两边进行广度优先搜索,算法思路:从起点和终点分别开始bfs。
2.2 双向广度优先搜索经典题目8数码
- 问题描述:在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格用0来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。
- 输入:输入初始状态,一行九个数字,空格用0表示
- 输出:只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数(一定能到达目标状态)
- 样例输入:283104765
- 样例输出:4
- 样例解析:
283 203 023 123 123
104 -> 184 -> 184 -> 084 -> 804
765 765 765 765 765
- 思路:经典bfs题目,直接搜会很麻烦,中间会出现大量重复的状态,会浪费很多时间,因此为了去除重复状态,优化搜索效率,可以把这个三行转换成一个9位的字符串。然后会发现这样转换后,每一种状态对应唯一的一个字符串,因此队列中只需要保存字符串(状态)即可,对于每一个整数都考虑是由哪一个字符串转换得到的,同时相应步数加1,map会实现相同状态下的自动去重,十分方便,效率就会大大提升,但是在搜索的时候,还是需要转换回矩阵去判断0该往哪走。
- 参考代码:
#include<bits/stdc++.h>
using namespace std;
const int N=3;
bool check(int x,int y){
if(x>=0&&y>=0&&x<N&&y<N) return true;