1 条题解
-
0
很明显的一道搜索,但是重点在怎么剪枝上。
很容易想到,如果我来过这里,并且方向是一致的,就可以不用看了。注意:一定要方向一致,毕竟可能出现交叉的情况;而且,在标记的过程中也要注意之前有没有标记。
代码
#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; }
信息
- ID
- 2420
- 时间
- 4916ms
- 内存
- 1024MiB
- 难度
- 提高
- 标签
- 递交数
- 5
- 已通过
- 1
- 上传者