1 条题解
-
0
#include <bits/stdc++.h> using namespace std; const int MAXN = 250; const int MAXQ = 100000; const int MAXTOT = 250 * 4 + 250 * 4; int n, m, Q; int dx[] = {0, 0, -1, 1}; int dy[] = {-1, 1, 0, 0}; bool g[MAXN + 5][MAXN + 5]; // 每个点上下左右能到的位置 pair<int, int> nxt[MAXN + 5][MAXN + 5][4]; // 有效点 int tot, idx[MAXN + 5][MAXN + 5]; pair<int, int> p[MAXTOT + 5]; // 每对有效点之间的图 tot * tot vector<pair<int, int>> e[MAXTOT + 5][MAXTOT + 5]; queue<pair<int, int>> q; int dis[MAXTOT + 5][MAXTOT + 5]; bool vis[MAXTOT + 5][MAXTOT + 5]; int main() { ios::sync_with_stdio(false); cin.tie(0); cin >> n >> m >> Q; for (int i = 0; i <= n + 1; i++) g[0][i] = g[i][0] = g[n + 1][i] = g[i][n + 1] = true; for (int i = 1; i <= m; i++) { int x, y; cin >> x >> y; g[x][y] = true; } // 预处理每个点上下左右能到的位置,可以优化,但是不优化也能过 // 为了可读性,就不优化了 for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) { if (g[i][j]) continue; for (int k = 0; k <= 3; k++) { if (g[i + dx[k]][j + dy[k]]) { idx[i][j] = ++tot; p[tot] = {i, j}; } for (int x = i, y = j; !g[x][y]; x += dx[k], y += dy[k]) nxt[i][j][k] = {x, y}; } } // 有效点对之间建反图 for (int i = 1; i <= tot; i++) for (int j = 1; j <= tot; j++) for (int k = 0; k <= 3; k++) { pair<int, int> pi = nxt[p[i].first][p[i].second][k]; pair<int, int> pj = nxt[p[j].first][p[j].second][k]; int ii = idx[pi.first][pi.second]; int jj = idx[pj.first][pj.second]; // i,j -> ii,jj e[ii][jj].push_back({i, j}); } // 重合点反向 bfs 预处理有效点对的 dis for (int i = 1; i <= tot; i++) { q.push({i, i}); dis[i][i] = 1; vis[i][i] = true; } while (!q.empty()) { int a = q.front().first; int b = q.front().second; q.pop(); for (int i = 0; i < e[a][b].size(); i++) { int aa = e[a][b][i].first; int bb = e[a][b][i].second; if (vis[aa][bb]) continue; dis[aa][bb] = dis[a][b] + 1; vis[aa][bb] = true; q.push({aa, bb}); } } // 回答每个问题,每个问题走一步之后就能到有效点对上 while (Q--) { int a, b, c, d; cin >> a >> b >> c >> d; if (a == c && b == d) { cout << "0\n"; continue; } int ans = -1; for (int i = 0; i <= 3; i++) { // 走了一个 i 方向可以到 (aa,bb),(cc,dd) int aa = nxt[a][b][i].first; int bb = nxt[a][b][i].second; int cc = nxt[c][d][i].first; int dd = nxt[c][d][i].second; int now = dis[idx[aa][bb]][idx[cc][dd]]; if (!now) continue; if (ans == -1 || now < ans) ans = now; } cout << ans << "\n"; } return 0; }
- 1
信息
- ID
- 1790
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 5
- 标签
- 递交数
- 5
- 已通过
- 1
- 上传者