Colored Portals§
预处理每个位置左侧最靠近的某种城市位置和右侧最靠近的某种城市位置。
乱搞就行了。
#include <bits/stdc++.h> #define int long long constexpr int N = 2e5 + 10, INF = 1e9; int l[N][4][4], r[N][4][4]; void solve() { int n, q; std::cin >> n >> q; std::vector<std::string> a(n + 1); for (int i = 1; i <= n; i++) { std::cin >> a[i]; } std::vector<int> id(256); id['B'] = 0; id['G'] = 1; id['R'] = 2; id['Y'] = 3; for (int i = 0; i <= n + 1; i++) { for (int u = 0; u < 4; u++) { for (int v = 0; v < 4; v++) { r[i][u][v] = INF; l[i][u][v] = INF; } } } for (int i = 1; i <= n; i++) { int x = id[a[i][0]], y = id[a[i][1]]; for (int u = 0; u < 4; u++) { for (int v = 0; v < 4; v++) { l[i][u][v] = l[i - 1][u][v]; } } l[i][x][y] = i; l[i][y][x] = i; } for (int i = n; i >= 1; i--) { int x = id[a[i][0]], y = id[a[i][1]]; for (int u = 0; u < 4; u++) { for (int v = 0; v < 4; v++) { r[i][u][v] = r[i + 1][u][v]; } } r[i][x][y] = i; r[i][y][x] = i; } while (q--) { int x, y; std::cin >> x >> y; int ans = INF; for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { int u = id[a[x][i]], v = id[a[y][j]]; if (l[x][u][v] != INF) { ans = std::min(ans, abs(x - l[x][u][v]) + abs(y - l[x][u][v])); } if (r[x][u][v] != INF) { ans = std::min(ans, abs(x - r[x][u][v]) + abs(y - r[x][u][v])); } if (l[y][u][v] != INF) { ans = std::min(ans, abs(x - l[y][u][v]) + abs(y - l[y][u][v])); } if (r[y][u][v] != INF) { ans = std::min(ans, abs(x - r[y][u][v]) + abs(y - r[y][u][v])); } } } if (ans >= INF) ans = -1; std::cout << ans << '\n'; } } signed main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); int t; std::cin >> t; while (t--) { solve(); } return 0; }