Files
python/TangDou/AcWing/Dfs/1112.md
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

183 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## [$AcWing$ $1112$. 迷宫](https://www.acwing.com/problem/content/1114/)
### 一、题目描述
一天$Extense$在森林里探险的时候不小心走入了一个迷宫,迷宫可以看成是由 $n∗n$ 的格点组成,每个格点只有$2$种状态,`.`和`#`,前者表示 **可以通行** 后者表示 **不能通行**。
同时当$Extense$处在某个格点时,他只能移动到东南西北(或者说**上下左右**)四个方向之一的相邻格点上,$Extense$想要从点$A$走到点$B$,问在不走出迷宫的情况下能不能办到。
如果起点或者终点有一个不能通行(为`#`),则看成无法办到。
**注意**:$A、B$不一定是两个不同的点。
**输入格式**
第$1$行是测试数据的组数 $k$,后面跟着 $k$ 组输入。
每组测试数据的第1行是一个正整数 $n$,表示迷宫的规模是 $n∗n$ 的。
接下来是一个 $n∗n$ 的矩阵,矩阵中的元素为`.`或者`#`。
再接下来一行是 $4$ 个整数 $h_a,l_a,h_b,l_b$,描述 $A$ 处在第 $h_a$ 行, 第 $l_a$ 列,$B$ 处在第 $h_b$ 行, 第 $l_b$ 列。
注意到 $h_a,l_a,h_b,l_b$ 全部是从 $0$ 开始计数的。
**输出格式**
$k$行,每行输出对应一个输入。
能办到则输出`YES`,否则输出`NO`。
**数据范围**
$1≤n≤100$
**输入样例**:
```cpp {.line-numbers}
2
3
.##
..#
#..
0 0 2 2
5
.....
###.#
..#..
###..
...#.
0 0 4 0
```
**输出样例**:
```cpp {.line-numbers}
YES
NO
```
### 二、$dfs$
```cpp {.line-numbers}
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
// dfs只能求出来是否连通,第一次搜索到时并不能保证是最短距离
// bfs也可以做,可以保证第一次到达时是最短距离
// dfs好处是代码短,按时间排名,那么先AC的同学排名靠前
// 用标记数组进行标记,每个位置只使用一次,性能N*N
const int N = 110;
int n;
char g[N][N]; // 地图
int xa, ya, xb, yb;
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};
bool st[N][N]; // 是否走过
bool flag;
void dfs(int x, int y) {
if (x == xb && y == yb) {
flag = true;
return;
}
for (int i = 0; i < 4; i++) {
int tx = x + dx[i], ty = y + dy[i];
if (tx < 0 || tx == n || ty < 0 || ty == n) continue;
if (st[tx][ty]) continue;
if (g[tx][ty] == '#') continue;
st[tx][ty] = true;
dfs(tx, ty);
}
}
int main() {
int T;
cin >> T;
while (T--) {
cin >> n;
for (int i = 0; i < n; i++) cin >> g[i];
cin >> xa >> ya >> xb >> yb;
// 多组测试数组,每次初始化0
memset(st, 0, sizeof st);
flag = false;
// 这小坑坑挺多啊
if (g[xa][ya] == '#' || g[xb][yb] == '#') {
puts("NO");
continue;
}
st[xa][ya] = true;
dfs(xa, ya);
if (flag)
puts("YES");
else
puts("NO");
}
return 0;
}
```
### 三、$bfs$
```cpp {.line-numbers}
#include <bits/stdc++.h>
using namespace std;
struct Node {
int x;
int y;
int step;
};
const int N = 110;
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};
char g[N][N];
bool st[N][N];
int n;
int xa, ya, xb, yb; // 不能使用x1,y1这样的变量名,可能是万能头中有重复声明
bool flag;
void bfs() {
flag = false;
if (g[xa][ya] == '#') return;
if (g[xb][yb] == '#') return;
memset(st, 0, sizeof st);
if (xa == xb && ya == yb) {
flag = true;
return;
}
queue<Node> q;
q.push({xa, ya, 0});
st[xa][ya] = true;
while (q.size()) {
auto t = q.front();
q.pop();
for (int i = 0; i < 4; i++) {
int x = t.x + dx[i], y = t.y + dy[i];
if (x < 0 || x >= n || y < 0 || y >= n) continue;
if (st[x][y]) continue;
if (g[x][y] == '#') continue;
if (x == xb && y == yb) {
flag = true;
return;
}
q.push({x, y, t.step + 1});
st[x][y] = true;
}
}
}
int main() {
int T;
cin >> T;
while (T--) {
cin >> n;
for (int i = 0; i < n; i++) cin >> g[i];
cin >> xa >> ya >> xb >> yb;
bfs();
if (flag)
cout << "YES" << endl;
else
cout << "NO" << endl;
}
return 0;
}
```