测评会员优惠活动进行中 · 开通 VIP,有效期内测评不限次 VIP 优惠中 · 测评不限次 立即查看

A18277. 空间折叠

填空题 困难

题目描述

空间折叠

题目描述

在古老的星尘遗迹中,地面被划分为 H 行 W 列的石板网格。

每块石板要么是完好的(用.表示),要么是破碎的(用#表示),只有完好石板才能安全站立。

你从入口 (Ch,Cw) 出发,要前往祭坛 (Dh,Dw)。

入口和祭坛保证是完好石板,且位置不同。

你可以执行以下两种行动:

步行:向上、下、左、右移动到相邻的完好石板。该行动不消耗能量。

空间折叠:以当前石板为中心,向 (5times5) 的方形区域(即行偏移 -2 到 +2,列偏移 -2 到 +2)内的任意完好石板瞬间传送。该行动消耗 1 点能量,且落点不能超出遗迹边界。

求从入口到祭坛所需的最少能量消耗,无法到达则输出 (-1)。

输入格式

第一行:两个整数 (H, W)

第二行:两个整数 ((Ch,Cw)(入口坐标)

第三行:两个整数 (Dh,Dw)(祭坛坐标)

接下来 H 行:每行一个长度为 W 的字符串,‘.’  代表通路,‘#’ 代表障碍

输出格式输出最少消耗的能量数值;不可达输出 -1

输入样例 1

4 4
1 1
4 4
..#.
..#.
.#..
.#..

输出样例1

1

输入样例 2

4 4
1 4
4 1
.##.
####
####
.##.

输出样例2

-1

输入样例 3

4 4
2 2
3 3
....
....
....
....

输出样例3

0

输入样例 4

4 5
1 2
2 5
#.###
####.
#..##
#..##

输出样例4

2

参考答案

#include <bits/stdc++.h> using namespace std; using pii = pair<int, int>; const int MAXN = 1005; const int INF = 0x3f3f3f3f; int H, W; char grid[MAXN][MAXN]; int dist[MAXN][MAXN]; // 普通四方向步行偏移 int dir4[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cin >> H >> W; int ch, cw, dh, dw; cin >> ch >> cw >> dh >> dw; // 输入下标1转0 int sx = ch - 1, sy = cw - 1; int tx = dh - 1, ty = dw - 1; for (int i = 0; i < H; i++) cin >> grid[i]; memset(dist, 0x3f, sizeof dist); dist[sx][sy] = 0; deque<pii> dq; dq.emplace_back(sx, sy); while (!dq.empty()) { auto [x, y] = dq.front(); dq.pop_front(); int curCost = dist[x][y]; // 到达终点直接提前输出答案 if (x == tx && y == ty) break; // 行动1:步行,代价0 for (auto &d : dir4) { int nx = x + d[0], ny = y + d[1]; if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue; if (grid[nx][ny] == '#') continue; if (dist[nx][ny] > curCost) { dist[nx][ny] = curCost; dq.emplace_front(nx, ny); } } // 行动2:空间折叠,5*5范围,代价+1 for (int dr = -2; dr <= 2; dr++) { for (int dc = -2; dc <= 2; dc++) { int nx = x + dr, ny = y + dc; if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue; if (grid[nx][ny] == '#') continue; if (dist[nx][ny] > curCost + 1) { dist[nx][ny] = curCost + 1; dq.emplace_back(nx, ny); } } } } int ans = dist[tx][ty]; cout << (ans == INF ? -1 : ans) << '\n'; return 0; }
上一题 下一题