题目思路各位大佬已经讲得很清楚了,就是将两个靠近墙的点进行连边,然后轻松板子 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;
}