$\Huge\color{orchid}{点击此处获取更多干货}$
BFS
本问题和847.点的层次其实是大致相同的问题,并且由于搜索范围从图结构变成了矩阵,前驱后继关系更加明确也更加容易表示了,都属于BFS模板问题,和最短路问题也有相通之处,对原理就不多说了,可以点击上面的链接自行查阅847题解
对于这个问题,只需要关注几个代码中的细节即可。一是坐标状态和访问记录,都可以放在距离表中,如果用无穷大来表示未访问的话,那么对于无法访问的坐标,可以再用一个-1来表示,方便BFS的时候跳过它。二是自定义结构体Point,用它来替代对组pair表示二维的坐标点,是因为可以自定义x,y成员变量,比起first,second具有更加明确清晰的含义,但是如果要用它作比较的话,不要忘了重载运算符
C++ 代码
#pragma GCC optimize(2)
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
//二维点坐标
struct Point {
int x, y;
Point() {}
Point(int _x, int _y) : x(_x), y(_y) {}
//系统不会自动提供比较运算符重载,需要自己实现
bool operator==(const Point& p) const { //两个const,建议全写上
return (this->x == p.x) && (this->y == p.y);
}
};
//对应上下左右四个方向
int dx[4] = { 1, 0, -1, 0 }, dy[4] = { 0, 1, 0, -1 };
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n, m;
cin >> n >> m;
Point _Dest(n - 1, m - 1);
//矩阵按行优先存储,0就是起点,最后一个就是终点
int* dists = new int[n * m];
int st;
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
cin >> st;
//把墙的位置事先用-1在距离表中标注出来
dists[i * m + j] = (st == 1) ? -1 : 1e9 + 7;
}
}
//跟之前类似的BFS
dists[0] = 0;
queue<Point> q;
q.push(Point(0, 0));
while(!q.empty()) {
Point cur = q.front();
q.pop();
if(cur == _Dest) {
cout << dists[n * m - 1] << endl;
delete[] dists;
return 0;
}
int ox = cur.x, oy = cur.y;
for(int i = 0; i < 4; i++) {
int nx = ox + dx[i], ny = oy + dy[i];
//越界舍弃
if(nx < 0 || ny < 0 || nx >= n || ny >= m) {
continue;
}
//撞墙走不通
if(dists[nx * m + ny] == -1) {
continue;
}
//未访问的访问一下
if(dists[nx * m + ny] > dists[ox * m + oy] + 1) {
dists[nx * m + ny] = dists[ox * m + oy] + 1;
q.push(Point(nx, ny));
}
}
}
//这里一般来说要输出无解信息,但需求描述中保证了有解,可以省略
delete[] dists;
return 0;
}