Sample Input 1
5 5
…#…
#.#.#
##.##
#.#.#
…#…
Sample Output 1
1
Sample Input 2
5 7
. . . . . . .
######.
. . . . . . .
.######
…
Sample Output 2
0
Sample Input 3
8 8
.#######
########
########
########
########
########
########
#######.
Sample Output 3
5
题解
假设他在需要时才出拳,我们可以假设 2 × 2 的破坏方块区域与高桥所在的方格相邻。当高桥在标记的地方上时 (下图中的 T),在单次出拳后,他可以移动到任何标有 * 的方格,而不管这些方格的先前状态如何。
因此,我们可以假设步行到相邻地方的成本为 0 ,并且移动到任何 * 方格后一拳成本为1,执行01-BFS来解决问题。计算复杂度O(HW)。
双端队列BFS代码
#include <bits/stdc++.h>
using namespace std;
#define mem(a, b) memset(a, b, sizeof(a))
#define ll long long int
#define endl '\n'
typedef pair<int, int> PII;
const int mod = 998244353;
const int inf = 0x3f3f3f3f;
const int N = 1e4 + 7;
int n, m;
char a[N][N];
int dis[N][N];
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};
void bfs(int sx, int sy) {
mem(dis, inf);
deque<PII> q;
dis[sx][sy] = 0;
q.push_front({sx, sy});
while (!q.empty()) {
auto t = q.front();
q.pop_front();
int x = t.first, y = t.second;
for (int i = 0; i < 4; i++) {
int xx = dx[i] + x;
int yy = dy[i] + y;
if (xx < 1 || xx > n || yy < 1 || yy > m)
continue;
if (a[xx][yy] == '.') {
if (dis[x][y] < dis[xx][yy]) {
dis[xx][yy] = dis[x][y];
q.push_front({xx, yy});
}
} else {
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
int xxx = i + xx;
int yyy = j + yy;
if (xxx < 1 || xxx > n || yyy < 1 || yyy > m)
continue;
if (dis[x][y] + 1 < dis[xxx][yyy]) {
dis[xxx][yyy] = dis[x][y] + 1;
q.push_back({xxx, yyy});
}
}
}
}
}
}
}
signed main() {
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> a[i] + 1;
bfs(1, 1);
cout << dis[n][m] << endl;
return 0;
}
优先队列BFS代码 类似于Dijkstra
#include <bits/stdc++.h>
using namespace std;
#define mem(a, b) memset(a, b, sizeof(a))
#define ll long long int
#define endl '\n'
typedef pair<int, int> PII;
const int mod = 998244353;
const int inf = 0x3f3f3f3f;
const int N = 1e4 + 7;
int n, m;
typedef pair<int, PII> PIII;
char a[N][N];
int dis[N][N];
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};
void bfs(int sx, int sy) {
mem(dis, inf);
priority_queue<PIII, vector<PIII>, greater<PIII>> q;
dis[sx][sy] = 0;
q.push({dis[sx][sy], {sx, sy}});
while (!q.empty()) {
auto t = q.top();
q.pop();
int dist = t.first;
int x = t.second.first, y = t.second.second;
for (int i = 0; i < 4; i++) {
int xx = dx[i] + x;
int yy = dy[i] + y;
if (xx < 1 || xx > n || yy < 1 || yy > m)
continue;
if (a[xx][yy] == '.') {
if (dist < dis[xx][yy]) {
dis[xx][yy] = dist;
q.push({dis[xx][yy], {xx, yy}});
}
} else {
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
int xxx = i + xx;
int yyy = j + yy;
if (xxx < 1 || xxx > n || yyy < 1 || yyy > m)
continue;
if (dist + 1 < dis[xxx][yyy]) {
dis[xxx][yyy] = dist + 1;
q.push({dis[xxx][yyy], {xxx, yyy}});
}
}
}
}
}
}
}
signed main() {
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> a[i] + 1;
bfs(1, 1);
cout << dis[n][m] << endl;
return 0;
}