제출 #884986

#제출 시각아이디문제언어결과실행 시간메모리
884986AlcabelMaze (JOI23_ho_t3)C++17
94 / 100
2028 ms294472 KiB
#pragma GCC optimize("O3", "Ofast", "unroll-loops") #include <bits/stdc++.h> using namespace std; const int inf = 1e7; const pair<int, int> deltas[4] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; vector<string> a; vector<vector<int>> vis, dist; int r, c, mini, minj, maxi, maxj, tt; vector<pair<int, int>> q; void dfs(int i, int j) { q.emplace_back(i, j); vis[i][j] = tt; for (const auto& [di, dj] : deltas) { if (i + di >= mini && i + di <= maxi && j + dj >= minj && j + dj <= maxj && vis[i + di][j + dj] < tt && dist[i + di][j + dj] >= dist[i][j]) { dist[i + di][j + dj] = dist[i][j]; dfs(i + di, j + dj); } } } void solve() { int n; cin >> r >> c >> n; int sr, sc, gr, gc; cin >> sr >> sc >> gr >> gc; --sr, --sc, --gr, --gc; a.resize(r); for (int i = 0; i < r; ++i) { cin >> a[i]; } vis.resize(r, vector<int>(c, -1)); dist.resize(r, vector<int>(c, inf)); vector<vector<int>> nxt(r, vector<int>(c, -1)); vector<pair<int, int>> ext; dist[sr][sc] = 0; q.emplace_back(sr, sc); tt = -1; ext.reserve(r * c); q.reserve(r * c); while (dist[gr][gc] == inf) { ++tt; while (!q.empty()) { auto [i, j] = q.back(); q.pop_back(); if (vis[i][j] == tt) { continue; } vis[i][j] = tt; ext.emplace_back(i, j); for (const auto& [di, dj] : deltas) { int newi = i + di, newj = j + dj; if (newi >= 0 && newi < r && newj >= 0 && newj < c && a[newi][newj] == '.' && dist[newi][newj] == inf) { dist[newi][newj] = dist[i][j]; q.emplace_back(newi, newj); } } } for (int iter = 0; iter < 4; ++iter) { ++tt; sort(ext.begin(), ext.end()); if (iter == 0) { // up int lastI = -1, start = -1; pair<int, int> segj = {0, -1}; bool sameI; for (auto [i, j] : ext) { sameI = (lastI == i); if (lastI == i && segj.second + 1 == j) { ++segj.second; } else { for (int k = segj.first; k <= segj.second; ++k) { nxt[lastI][k] = segj.second + 1; } lastI = i, segj = {j, j}; } mini = max(0, i - n), minj = max(0, j - n + 1); maxi = min(r - 1, i - 1), maxj = min(c - 1, j + n - 1); if (i - 1 >= 0) { int newD = dist[i][j] + 1; if (sameI) { j = max(j, start); } start = maxj + 1; --i; if (j <= maxj && dist[i][j] == newD - 1) { j = nxt[i][j]; } /*while (j <= maxj && (vis[i][j] == tt || dist[i][j] == newD - 1)) { ++j; }*/ if (j <= maxj && dist[i][j] > newD - 1) { dist[i][j] = newD; dfs(i, j); } } } } else if (iter == 1) { // left int lastJ = -1, start = -1; pair<int, int> segi = {0, -1}; bool sameJ; for (auto [j, i] : ext) { i = -i; sameJ = (lastJ == j); if (lastJ == j && segi.first - 1 == i) { --segi.first; } else { for (int k = segi.first; k <= segi.second; ++k) { nxt[k][lastJ] = segi.first - 1; } lastJ = j, segi = {i, i}; } mini = max(0, i - n + 1), minj = max(0, j - n); maxi = min(r - 1, i + n - 1), maxj = min(c - 1, j - 1); if (j - 1 >= 0) { int newD = dist[i][j] + 1; if (sameJ) { i = min(i, start); } start = mini - 1; --j; if (i >= mini && dist[i][j] == newD - 1) { i = nxt[i][j]; } /*while (i >= mini && (vis[i][j] == tt || dist[i][j] == newD - 1)) { --i; }*/ if (i >= mini && dist[i][j] > newD - 1) { dist[i][j] = newD; dfs(i, j); } } } } else if (iter == 2) { // down int lastI = -1, start = -1; pair<int, int> segj = {0, -1}; bool sameI; for (auto [i, j] : ext) { i = -i, j = -j; sameI = (lastI == i); if (lastI == i && segj.first - 1 == j) { --segj.first; } else { for (int k = segj.first; k <= segj.second; ++k) { nxt[lastI][k] = segj.first - 1; } lastI = i, segj = {j, j}; } mini = max(0, i + 1), minj = max(0, j - n + 1); maxi = min(r - 1, i + n), maxj = min(c - 1, j + n - 1); if (i + 1 < r) { int newD = dist[i][j] + 1; if (sameI) { j = min(j, start); } start = minj - 1; ++i; if (j >= minj && dist[i][j] == newD - 1) { j = nxt[i][j]; } /*while (j >= minj && (vis[i][j] == tt || dist[i][j] == newD - 1)) { --j; }*/ if (j >= minj && dist[i][j] > newD - 1) { dist[i][j] = newD; dfs(i, j); } } } } else { // right int lastJ = -1, start = -1; pair<int, int> segi = {0, -1}; bool sameJ; for (auto [j, i] : ext) { j = -j; sameJ = (lastJ == j); if (lastJ == j && segi.second + 1 == i) { ++segi.second; } else { for (int k = segi.first; k <= segi.second; ++k) { nxt[k][lastJ] = segi.second + 1; } lastJ = j, segi = {i, i}; } mini = max(0, i - n + 1), minj = max(0, j + 1); maxi = min(r - 1, i + n - 1), maxj = min(c - 1, j + n); if (j + 1 < c) { int newD = dist[i][j] + 1; if (sameJ) { i = max(i, start); } start = maxi + 1; ++j; if (i <= maxi && dist[i][j] == newD - 1) { i = nxt[i][j]; } /*while (i <= maxi && (vis[i][j] == tt || dist[i][j] == newD - 1)) { ++i; }*/ if (i <= maxi && dist[i][j] > newD - 1) { dist[i][j] = newD; dfs(i, j); } } } } for (int i = 0; i < (int)ext.size(); ++i) { ext[i].first = -ext[i].first; swap(ext[i].first, ext[i].second); } } ext.clear(); } cout << dist[gr][gc] << '\n'; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); #ifdef LOCAL freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout); int T = 1; cin >> T; while (T--) { solve(); cerr << "-----------\n"; cout << "-----------\n"; } #else int T = 1; // cin >> T; while (T--) { solve(); } #endif return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...