Submission #769554

#TimeUsernameProblemLanguageResultExecution timeMemory
769554danikoynovMaze (JOI23_ho_t3)C++14
100 / 100
1680 ms634860 KiB
#include<bits/stdc++.h> #define endl '\n' using namespace std; typedef long long ll; void speed() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); } const int maxn = 6e6 + 10, block = sqrt(maxn) + 10; struct cell { int x, y; cell(int _x = 0, int _y = 0) { x = _x; y = _y; } cell add(const cell &r) const { cell d; d.x = x + r.x; d.y = y + r.y; return d; } }; cell neib[4] = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}}; int n, m, h; vector < int > a[block], tr[block], tl[block]; vector < int > tu[block], td[block]; vector < int > ver_idx[block]; int stx, sty, enx, eny; int nxt; int dist[5 * maxn]; int is_div[maxn]; void add_edges_row(int row, int i, int j, int ver, vector < int > &vec) { if (j - i + 1 == 2 * h - 1) { vec.push_back(tr[row][i]); vec.push_back(tl[row][j]); } else { if (i == 1) vec.push_back(tl[row][j]); else { int to = i; if (!is_div[i]) to = 2 * h - 1 - i % (2 * h - 1) + i; if (to >= j) vec.push_back(tr[row][i]); else { vec.push_back(tr[row][i]); vec.push_back(tl[row][j]); } } } } void add_edges_col(int col, int i, int j, int ver, vector < int > &vec) { if (j - i + 1 == 2 * h - 1) { vec.push_back(td[i][col]); vec.push_back(tu[j][col]); } else { if (i == 1) vec.push_back(tu[j][col]); else { int to = i; if (!is_div[i]) to = 2 * h - 1 - i % (2 * h - 1) + i; if (to >= j) vec.push_back(td[i][col]); else { vec.push_back(td[i][col]); vec.push_back(tu[j][col]); } } } } int type[5 * maxn]; pair < int, int > cor[5 * maxn]; void solve() { cin >> n >> m >> h; cin >> stx >> sty; cin >> enx >> eny; for (int i = 0; i <= max(n, m); i ++) { if (i % (2 * h - 1) == 0) is_div[i] = 1; } for (int i = 1; i <= n; i ++) { a[i].resize(m + 2); tl[i].resize(m + 2); tr[i].resize(m + 2); td[i].resize(m + 2); tu[i].resize(m + 2); ver_idx[i].resize(m + 2); string s; cin >> s; char c; for (int j = 1; j <= m; j ++) { c = s[j - 1]; if (c == '.') a[i][j] = 0; else a[i][j] = 1; } } int cnt = 0; nxt = n * m; for (int i = 1; i <= n; i ++) { for (int j = 1; j <= m; j ++) { ver_idx[i][j] = ++ cnt; } } for (int i = 1; i <= n; i ++) { for (int j = 1; j <= m; j ++) { tr[i][j] = ++ nxt; type[nxt] = 1; cor[nxt] = {i, j}; tl[i][j] = ++ nxt; type[nxt] = 2; cor[nxt] = {i, j}; } } for (int j = 1; j <= m; j ++) { for (int i = 1; i <= n; i ++) { tu[i][j] = ++ nxt; type[nxt] = 4; cor[nxt] = {i, j}; td[i][j] = ++ nxt; type[nxt] = 3; cor[nxt] = {i, j}; } } for (int i = 1; i <= nxt; i ++) dist[i] = 1e9; deque < int > dq; dq.push_back(ver_idx[stx][sty]); dist[ver_idx[stx][sty]] = 0; vector < int > sus; while(!dq.empty()) { int cur = dq.front(); dq.pop_front(); if (cur == ver_idx[enx][eny]) { cout << dist[cur] << endl; return; } if (cur <= n * m) { cell c(cur / m + 1, cur % m); if (cur % m == 0) c.x --, c.y = m; for (int i = 0; i < 4; i ++) { cell nb = neib[i].add(c); if (nb.x == 0 || nb.x == n + 1 || nb.y == 0 || nb.y == m + 1 || a[nb.x][nb.y] == 1) continue; int u = ver_idx[nb.x][nb.y]; int w = 0; if (dist[u] > dist[cur] + w) { dist[u] = dist[cur] + w; if (w == 0) dq.push_front(u); else dq.push_back(u); } } int i = c.x; int j = c.y; sus.clear(); int st_row = max(1, i - h), en_row = min(n, i + h); int st_col = max(1, j - h), en_col = min(m, j + h); int fs_row = st_row, ds_row = en_row; if (fs_row == i - h) fs_row ++; if (ds_row == i + h) ds_row --; bool f1 = false, f2 = false; if (st_row == i - h) { if (st_col == j - h) st_col ++, f1 = true; if (en_col == j + h) en_col --, f2 = true; } add_edges_row(st_row, st_col, en_col, ver_idx[i][j], sus); if (st_row == i - h) { if (f1) st_col --; if (f2) en_col ++; } f1 = f2 = false; if (en_row == i + h) { if (st_col == j - h) st_col ++, f1 = true; if (en_col == j + h) en_col --, f2 = true; } add_edges_row(en_row, st_col, en_col, ver_idx[i][j], sus); if (en_row == i + h) { if (f1) st_col --; if (f2) en_col ++; } f1 = f2 = false; if (st_col == j - h) { if (st_row == i - h) st_row ++, f1 = true; if (en_row == i + h) en_row --, f2 = true; } add_edges_col(st_col, st_row, en_row, ver_idx[i][j], sus); if (st_col == j - h) { if (f1) st_row --; if (f2) en_row ++; } /// right col f1 = f2 = false; if (en_col == j + h) { if (st_row == i - h) st_row ++, f1 = true; if (en_row == i + h) en_row --, f2 = true; } add_edges_col(en_col, st_row, en_row, ver_idx[i][j], sus); if (en_col == j + h) { if (f1) st_row --; if (f2) en_row ++; } for (int u : sus) { if (dist[u] > dist[cur] + 1) { dist[u] = dist[cur] + 1; dq.push_back(u); } } } if (type[cur] == 1) { int x = cor[cur].first, y = cor[cur].second; if (y != m && !is_div[y]) { if (dist[tr[x][y + 1]] > dist[cur]) { dist[tr[x][y + 1]] = dist[cur]; dq.push_front(tr[x][y + 1]); } } if (dist[ver_idx[x][y]] > dist[cur]) { dist[ver_idx[x][y]] = dist[cur]; dq.push_front(ver_idx[x][y]); } } if (type[cur] == 2) { int x = cor[cur].first, y = cor[cur].second; if (!is_div[y - 1]) { if (dist[tl[x][y - 1]] > dist[cur]) { dist[tl[x][y - 1]] = dist[cur]; dq.push_front(tl[x][y - 1]); } } if (dist[ver_idx[x][y]] > dist[cur]) { dist[ver_idx[x][y]] = dist[cur]; dq.push_front(ver_idx[x][y]); } } if (type[cur] == 3) { int x = cor[cur].first, y = cor[cur].second; if (x != n && !is_div[x]) { if (dist[td[x + 1][y]] > dist[cur]) { dist[td[x + 1][y]] = dist[cur]; dq.push_front(td[x + 1][y]); } } if (dist[ver_idx[x][y]] > dist[cur]) { dist[ver_idx[x][y]] = dist[cur]; dq.push_front(ver_idx[x][y]); } } if (type[cur] == 4) { int x = cor[cur].first, y = cor[cur].second; if (!is_div[x - 1]) { if (dist[tu[x - 1][y]] > dist[cur]) { dist[tu[x - 1][y]] = dist[cur]; dq.push_front(tu[x - 1][y]); } } if (dist[ver_idx[x][y]] > dist[cur]) { dist[ver_idx[x][y]] = dist[cur]; dq.push_front(ver_idx[x][y]); } } } /**for (int i = 1; i <= n; i ++, cout << endl) for (int j = 1; j <= m; j ++) cout << dist[ver_idx[i][j]] << " ";*/ int ans = dist[ver_idx[enx][eny]]; for (int i = 1; i <= n; i ++) for (int j = 1; j <= m; j ++) { if (abs(i - enx) <= h && abs(j - eny) <= h) { if (abs(i - enx) + abs(j - eny) != 2 * h) { ans = min(ans, dist[ver_idx[i][j]] + 1); } } } cout << ans << endl; } int main() { ///freopen("test.txt", "r", stdin); speed(); solve(); return 0; } /** 3 3 2 1 1 3 3 .#. ##. ... */
#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...