题目思路各位大佬已经讲得很清楚了,就是将两个靠近墙的点进行连边,然后轻松板子 bfs 即可。
本人并不觉得这道题目码量很大,qwq。
#include <bits/stdc++.h>
#define L(i, a, b) for(int i = (a); i <= (b); i++)
#define R(i, a, b) for(int i = (a); i >= (b); i--)
#define pii pair<int, int>
#define ll long long
#define vi vector<int>
#define P 1e9+7917120411
using namespace std;
const int N = 1e3 + 10;
int a[N][N], n, dis[N][N];
queue<int> qx, qy;
const int dx[] = {0, 0, -1, 1};
const int dy[] = {-1, 1, 0, 0};
int bfs(int x, int y) {
qx.push(x), qy.push(y);
memset(dis, 0x3f, sizeof(dis));
dis[x][y] = 0;
vector<int> xx, yy;
while(!qx.empty()) {
x = qx.front(), y = qy.front();
qx.pop(); qy.pop();
xx.clear(); yy.clear();
for(int i = 0; i < 4; i++) {
int bx = x + dx[i], by = y + dy[i];
if(a[bx][by]) xx.push_back(x-bx), yy.push_back(y-by);
if(bx < 1 || by < 1 || bx > n || by > n) continue;
if(a[bx][by]) continue;
if(dis[bx][by] > dis[x][y]+1) {
dis[bx][by] = dis[x][y] + 1;
qx.push(bx); qy.push(by);
}
}
for(int i = 0; i < xx.size(); i++) {
int bx = x+xx[i], by = y + yy[i];
while(!a[bx][by]) bx += xx[i], by += yy[i];
bx -= xx[i], by -= yy[i];
if(bx < 1 || by < 1 || bx > n || by > n) continue;
if(dis[bx][by] > dis[x][y]+1) {
dis[bx][by] = dis[x][y] + 1;
qx.push(bx); qy.push(by);
}
}
}
return dis[n][n];
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> n;
L(i, 1, n) a[0][i] = a[i][0] = a[i][n+1] = a[n+1][i] = 1;
L(i, 1, n) L(j, 1, n) cin >> a[i][j];
int ans = bfs(1, 1);
if(ans == dis[n+2][n+2]) cout << -1 << '\n';
else cout << ans;
return 0;
}