- 题解
- ABC246E 主教 2
ABC246E. 主教 2
- @ 2026-9-2 21:19:53
很明显的一道搜索,但是重点在怎么剪枝上。
很容易想到,如果我来过这里,并且方向是一致的,就可以不用看了。注意:一定要方向一致,毕竟可能出现交叉的情况;而且,在标记的过程中也要注意之前有没有标记。
代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
int T = 1;
const int N = 1500 + 10;
int n;
int ax, ay, bx, by;
char graph[N][N];
int dis[N][N];
bool vis[N][N][4];
void Bfs() {
memset(dis, 127, sizeof(dis));
queue<pair<int, int>> q;
q.push({ax, ay});
dis[ax][ay] = 0;
while (!q.empty()) {
int x = q.front().first, y = q.front().second;
q.pop();
if (!vis[x][y][0]) {
for (int nx = x, ny = y; nx >= 1 && ny >= 1; nx--, ny--) {
if (graph[nx][ny] == '#') break;
if (vis[nx][ny][0]) break;
vis[nx][ny][0] = true;
if (dis[nx][ny] > dis[x][y] + 1) {
dis[nx][ny] = dis[x][y] + 1;
q.push({nx, ny});
}
}
}
if (!vis[x][y][1]) {
for (int nx = x, ny = y; nx <= n && ny <= n; nx++, ny++) {
if (graph[nx][ny] == '#') break;
if (vis[nx][ny][1]) break;
vis[nx][ny][1] = true;
if (dis[nx][ny] > dis[x][y] + 1) {
dis[nx][ny] = dis[x][y] + 1;
q.push({nx, ny});
}
}
}
if (!vis[x][y][2]) {
for (int nx = x, ny = y; nx >= 1 && ny <= n; nx--, ny++) {
if (graph[nx][ny] == '#') break;
if (vis[nx][ny][2]) break;
vis[nx][ny][2] = true;
if (dis[nx][ny] > dis[x][y] + 1) {
dis[nx][ny] = dis[x][y] + 1;
q.push({nx, ny});
}
}
}
if (!vis[x][y][3]) {
for (int nx = x, ny = y; nx <= n && ny >= 1; nx++, ny--) {
if (graph[nx][ny] == '#') break;
if (vis[nx][ny][3]) break;
vis[nx][ny][3] = true;
if (dis[nx][ny] > dis[x][y] + 1) {
dis[nx][ny] = dis[x][y] + 1;
q.push({nx, ny});
}
}
}
}
if (dis[bx][by] > 1e9) cout << -1;
else cout << dis[bx][by];
}
void Solve() {
cin >> n;
cin >> ax >> ay >> bx >> by;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cin >> graph[i][j];
}
}
Bfs();
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
while (T--) {
Solve();
}
return 0;
}
1 条评论
-
张泊文 ⛰️ 登峰造极 LV 8 @ 2026-9-4 22:07:04你还是人类??
- 1