广搜.
不必在意有两只马,处理一个后重新初始化再次处理即可,剩下的就是很原始的bfs.
注意vis这个标记,在bfs中一个点第一次被遍历到时一定是最快/最短的路径,所以在vis标记之后就不需要再去这个点了.(隐性的剪枝)
如果用dfs+回溯来做的话,就必须等到所有的方案(剪枝后的)穷举之后才能得出答案,相比bfs效率会低很多.
bfs每标记一个vis,都是在向正确答案靠近一步.
dfs回溯完毕时,才能够"总结"出正确答案.
所以求到某已知状态的最短路的问题适合用bfs.
如果最终状态不给出的话,怎么用bfs呢?比如说吃奶酪.这时候暴力方法还是用dfs.
#include <algorithm> //最近改掉了代码风格,发现还是大括号不换行可读性会更高一些 #include <cstdio> #include <cstring> #include <iostream> #include <queue> using namespace std; int sx, sy, dx[12] = {-2, -2, -2, -2, -1, -1, 1, 1, 2, 2, 2, 2}, dy[12] = {-2, -1, 1, 2, -2, 2, -2, 2, -2, 2, -1, 1}; bool vis[30][30]; struct S { int x, y, t; }; queue<struct S> que; void bfs(){ que.push({sx, sy, 0}); vis[sx][sy] = true; while(!que.empty()){ struct S tmp = que.front(); que.pop(); if(tmp.x == 1 && tmp.y == 1){ printf("%d ", tmp.t); return; } for(int i = 0; i < 12; i++){ int nx = tmp.x + dx[i], ny = tmp.y + dy[i]; if(nx >= 1 && nx <= 25 && ny >= 1 && ny <= 25 && !vis[nx][ny]){ //马的起点是在(1,1),(20,20)的,但是没有说超出(20,20)没有棋盘,开到25防止可能的漏解 que.push({nx, ny, tmp.t + 1}); //注意也没有必要搜索越跳越远的情况 vis[nx][ny] = true; } } } } int main() { cin >> sx >> sy; bfs(); cin >> sx >> sy; memset(vis, 0, sizeof(vis)); while(!que.empty()) que.pop(); bfs(); return 0; }