This commit is contained in:
HuangHai
2025-08-30 18:35:01 +08:00
commit 1f397eca87
6258 changed files with 1487241 additions and 0 deletions

183
TangDou/AcWing/Dfs/1112.md Normal file
View File

@@ -0,0 +1,183 @@
## [$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;
}
```

View File

@@ -0,0 +1,63 @@
#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;
}

View File

@@ -0,0 +1,60 @@
#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;
}

156
TangDou/AcWing/Dfs/1113.md Normal file
View File

@@ -0,0 +1,156 @@
## [$AcWing$ $1113$. 红与黑](https://www.acwing.com/problem/content/1115/)
### 一、题目描述
有一间长方形的房子,地上铺了红色、黑色两种颜色的正方形瓷砖。
你站在其中一块 **黑色的瓷砖** 上,只能向相邻( **上下左右** 四个方向)的 **黑色** 瓷砖移动。
请写一个程序,计算你总共能够到达多少块黑色的瓷砖。
**输入格式**
输入包括多个数据集合。
每个数据集合的第一行是两个整数 $W$ 和 $H$,分别表示 $x$ 方向和 $y$ 方向瓷砖的数量。
在接下来的 $H$ 行中,每行包括 $W$ 个字符。每个字符表示一块瓷砖的颜色,规则如下
1)‘.’:黑色的瓷砖;
2)‘#’:红色的瓷砖;
3)‘@’:黑色的瓷砖,并且你站在这块瓷砖上。该字符在每个数据集合中唯一出现一次。
当在一行中读入的是两个零时,表示输入结束。
**输出格式**
对每个数据集合,分别输出一行,显示你从初始位置出发能到达的瓷砖数(记数时包括初始位置的瓷砖)。
**数据范围**
$1≤W,H≤20$
**输入样例**:
```cpp {.line-numbers}
6 9
....#.
.....#
......
......
......
......
......
#@...#
.#..#.
0 0
```
**输出样例**:
```cpp {.line-numbers}
45
```
### 二、$dfs$
```cpp {.line-numbers}
#include <bits/stdc++.h>
using namespace std;
const int N = 25;
// dfs 实现flood fill 算法
int n, m;
char g[N][N];
bool st[N][N];
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};
int cnt;
void dfs(int x, int y) {
// x,y贡献了1个结点数
cnt++;
st[x][y] = true;
for (int i = 0; i < 4; i++) {
int tx = x + dx[i], ty = y + dy[i];
if (tx < 0 || tx >= n || ty < 0 || ty >= m) continue;
if (g[tx][ty] != '.') continue;
if (st[tx][ty]) continue;
dfs(tx, ty);
}
}
int main() {
while (cin >> m >> n, n || m) { // 先输入列数,再输入行数,小坑
// 多组测试数据
memset(st, 0, sizeof st);
cnt = 0;
// 找起点
int x, y;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++) {
cin >> g[i][j];
if (g[i][j] == '@') x = i, y = j;
}
dfs(x, y);
printf("%d\n", cnt);
}
return 0;
}
```
### 三、$bfs$
```cpp {.line-numbers}
#include <bits/stdc++.h>
using namespace std;
const int N = 30;
struct Node {
int x;
int y;
};
char g[N][N];
int n, m;
int dx[] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
bool st[N][N];
int cnt;
void bfs(int x, int y) {
queue<Node> q;
q.push({x, y});
while (q.size()) {
Node t = q.front();
q.pop();
cnt++;
for (int i = 0; i < 4; i++) {
int tx = t.x + dx[i], ty = t.y + dy[i];
if (tx < 0 || tx >= n || ty < 0 || ty >= m) continue;
if (st[tx][ty]) continue;
if (g[tx][ty] != '.') continue;
st[tx][ty] = true;
q.push({tx, ty});
}
}
}
int main() {
while (cin >> m >> n, n || m) {
memset(st, 0, sizeof st);
cnt = 0;
int x, y;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> g[i][j];
if (g[i][j] == '@') x = i, y = j;
}
}
bfs(x, y);
printf("%d\n", cnt);
}
return 0;
}
```

View File

@@ -0,0 +1,52 @@
#include <bits/stdc++.h>
using namespace std;
const int N = 30;
struct Node {
int x;
int y;
};
char g[N][N];
int n, m;
int dx[] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
bool st[N][N];
int cnt;
void bfs(int x, int y) {
queue<Node> q;
q.push({x, y});
while (q.size()) {
Node t = q.front();
q.pop();
cnt++;
for (int i = 0; i < 4; i++) {
int tx = t.x + dx[i], ty = t.y + dy[i];
if (tx < 0 || tx >= n || ty < 0 || ty >= m) continue;
if (st[tx][ty]) continue;
if (g[tx][ty] != '.') continue;
st[tx][ty] = true;
q.push({tx, ty});
}
}
}
int main() {
while (cin >> m >> n, n || m) {
memset(st, 0, sizeof st);
cnt = 0;
int x, y;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> g[i][j];
if (g[i][j] == '@') x = i, y = j;
}
}
bfs(x, y);
printf("%d\n", cnt);
}
return 0;
}

View File

@@ -0,0 +1,48 @@
#include <bits/stdc++.h>
using namespace std;
const int N = 25;
// dfs 实现flood fill 算法
int n, m;
char g[N][N];
bool st[N][N];
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};
int cnt;
void dfs(int x, int y) {
// x,y贡献了1个结点数
cnt++;
st[x][y] = true;
for (int i = 0; i < 4; i++) {
int tx = x + dx[i], ty = y + dy[i];
if (tx < 0 || tx >= n || ty < 0 || ty >= m) continue;
if (g[tx][ty] != '.') continue;
if (st[tx][ty]) continue;
dfs(tx, ty);
}
}
int main() {
while (cin >> m >> n, n || m) { // 先输入列数,再输入行数,小坑
// 多组测试数据
memset(st, 0, sizeof st);
cnt = 0;
// 找起点
int x, y;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++) {
cin >> g[i][j];
if (g[i][j] == '@') x = i, y = j;
}
dfs(x, y);
printf("%d\n", cnt);
}
return 0;
}

View File

@@ -0,0 +1,32 @@
#include <bits/stdc++.h>
using namespace std;
const int N = 10;
int n;
int a[N], al;
bool st[N];
void dfs(int u) {
// 如果到达了终点
if (u == n + 1) {
for (int i = 0; i < n; i++)
printf("%d ", a[i]);
puts("");
return;
}
for (int i = 1; i <= n; i++)
if (!st[i]) {
a[al++] = i;
st[i] = true;
dfs(u + 1);
st[i] = false;
al--;
}
}
int main() {
cin >> n;
// 开始
dfs(1);
return 0;
}

66
TangDou/AcWing/Dfs/842.md Normal file
View File

@@ -0,0 +1,66 @@
##[$AcWing$ $842$. 排列数字](https://www.acwing.com/problem/content/description/844/)
### 一、题目描述
给定一个整数 $n$,将数字 $1∼n$ 排成一排,将会有很多种排列方法。
现在,请你按照字典序将所有的排列方法输出。
**输入格式**
共一行,包含一个整数 $n$。
**输出格式**
按字典序输出所有排列方案,每个方案占一行。
**数据范围**
$1≤n≤7$
**输入样例:**
```cpp {.line-numbers}
3
```
**输出样例:**
```cpp {.line-numbers}
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
```
### 二、实现代码
```cpp {.line-numbers}
#include <bits/stdc++.h>
using namespace std;
const int N = 10;
int n;
int a[N], al;
bool st[N];
void dfs(int u) {
// 如果到达了终点
if (u == n + 1) {
for (int i = 0; i < n; i++)
printf("%d ", a[i]);
puts("");
return;
}
for (int i = 1; i <= n; i++)
if (!st[i]) {
a[al++] = i;
st[i] = true;
dfs(u + 1);
st[i] = false;
al--;
}
}
int main() {
cin >> n;
// 开始
dfs(1);
return 0;
}
```

View File

@@ -0,0 +1,37 @@
#include <bits/stdc++.h>
using namespace std;
const int N = 20;
int path[N];
int n;
int b1[N], b2[N], b3[N];
void dfs(int u) {
if (u == n + 1) { // 全部行都摆上皇后
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (j == path[i])
printf("Q");
else
printf(".");
}
puts("");
}
puts("");
return;
}
for (int i = 1; i <= n; i++) { // x行y列
if (!b1[i] && !b2[u + i] && !b3[u - i + 8]) {
path[u] = i;
b1[i] = b2[u + i] = b3[u - i + 8] = 1;
dfs(u + 1);
b1[i] = b2[u + i] = b3[u - i + 8] = 0;
}
}
}
int main() {
cin >> n;
dfs(1);
return 0;
}

98
TangDou/AcWing/Dfs/843.md Normal file
View File

@@ -0,0 +1,98 @@
##[$AcWing$ $843$. $n$-皇后问题](https://www.acwing.com/problem/content/description/845/)
### 一、题目描述
$n$−皇后问题是指将 $n$ 个皇后放在 $n×n$ 的国际象棋棋盘上,使得皇后不能相互攻击到,即任意两个皇后都不能处于同一行、同一列或同一斜线上。
<center><img src='https://cdn.acwing.com/media/article/image/2019/06/08/19_860e00c489-1_597ec77c49-8-queens.png'></center>
现在给定整数 $n$,请你输出所有的满足条件的棋子摆法。
**输入格式**
共一行,包含整数 $n$。
**输出格式**
每个解决方案占 $n$ 行,每行输出一个长度为 $n$ 的字符串,用来表示完整的棋盘状态。
其中 $.$ 表示某一个位置的方格状态为空,$Q$ 表示某一个位置的方格上摆着皇后。
每个方案输出完成后,输出一个空行。
注意:行末不能有多余空格。
输出方案的顺序任意,只要不重复且没有遗漏即可。
**数据范围**
$1≤n≤9$
**输入样例:**
```cpp {.line-numbers}
4
```
**输出样例:**
```cpp {.line-numbers}
.Q..
...Q
Q...
..Q.
..Q.
Q...
...Q
.Q..
```
### 二、题目分析
<img src='https://cdn.acwing.com/media/article/image/2021/02/07/64630_957f747469-QQ%E6%88%AA%E5%9B%BE20210207131455.png'>
### 三、实现代码
```cpp {.line-numbers}
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10; // Q:为什么这里是110,还是最大是9吗?这是因为在下面的数组使用中,采用了+8的偏移策略,需要大一点,只要开不死,就往死里开!
int path[N];
int n;
int b1[N], b2[N], b3[N];
void dfs(int u) {
if (u == n + 1) { // 全部行都摆上皇后
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (j == path[i])
printf("Q");
else
printf(".");
}
puts("");
}
puts("");
return;
}
for (int i = 1; i <= n; i++) { // x行y列
/*
1、因为x上按行一行一行来的,所以不用考虑行的冲突,只需要考虑列、正对角线,反对角线三个方向。
2、b2[x+i] 因为同一正角线的位置,行+列是相等的,如果我们设置了 行+列使用过了,
那么,其它再检查到同一对角线时,就会发现行+列已使用过
3、b3[x - i + 8] 因为同一反对角线的位置,行-列是相等的,但可能行>列,也可能列>行,
这要看它是最长对角线的右上方还是左下方,右上方x>y,左下方x<y 为了防止出现负数数组下标,
所以,采用了加一个偏移量的办法,这样,不管是大于还是小于,都规划到一个下标大于零的位置上。
4、这里不能使用abs,因为 abs(x-y)与abs(y-x)不是一条反对角线!!!
为什么是8?就是因为n的范围是9,b3数组下标不越界即可!即1-9+8=0*/
if (!b1[i] && !b2[u + i] && !b3[u - i + 8]) {
path[u] = i;
b1[i] = b2[u + i] = b3[u - i + 8] = 1;
dfs(u + 1);
b1[i] = b2[u + i] = b3[u - i + 8] = 0;
}
}
}
int main() {
cin >> n;
dfs(1);
return 0;
}
```

View File

@@ -0,0 +1,39 @@
https://codeforces.com/problemset/problem/484/E?f0a28=1
https://www.luogu.com.cn/problem/CF484E
Q:本题为什么没有使用离散化?主席树到底需不需要离散化??
### 一、题目描述
给我们一组数,并给出$m$个询问,每个询问包括$l,r,w$三个数,询问我们在$l$到$r$这个区间内连续取$w$个数,使这$w$个数中的**最小值**尽可能的**大**,输出这个**最大的最小值**。
### 二、解题思路
首先我们先假设在当前的询问下$x$这个数可以成为连续$w$个数中的最小值($x$一定为某个数的值),然后把数列中大于等于$x$的数标为$1$,小于$x$的数标为$0$,那么如果我们求出这个$01$串中最长的$1$串长度为$s$,且$s>=w$的话,$x$就可以拿去更新当前答案,然后我们就枚举比$x$大的值看是否符合条件,当然这个枚举过程用二分实现。
用线段树求一串数中最长的$1$串,应该都做过。所以问题就变成了我们如何来建立这个$01$串,很显然,我们不可能去构造$n$棵线段树。假设有两个数$x,y$且$x>y$那么很显然$y$的$01$串是$x$的$01$串的基础上多添加了几个$1$,所以我们可以用可持续化线段树来维护当前$01$串下的最长$1$串的长度。
### 二、个人感悟过程
#### 1、主席树为什么要记录$[l,r]$,其它题的主席树也记录了左右边界吗?
答: 区间内第$k$小的数,也是记录了$l,r$,看来记录$l,r$是通用办法。
#### 2、在左前缀,右后缀,连续最大值这样的问题中,左右边界的长度都很关键,是直接记录len,还是通过记录l,r,计算出len?
答: 既然主席树中都需要记录$l,r$,那么
```c++
int len(){
return r-l+1;
}
```
就是标配了。
#### 3、$0$号版本似乎就是个架子,没有真正的内容。真正的内容都是一个一个,通过$insert$装载进来,生成一个个版本的。
答:事实上是这样的,但这个动作是标配,不能省略。
#### 4、 insert和query的参数
p参数都表示以此版本的线段树,是以p号节点为根节点的。
#### 5、insert和query的返回值
insert:返回的是新增加一个数值后,新创建的版本对应的根节点编号q
query:返回的是一个查询拼接后的结构体,以便读取mx,lx,rx等信息。

View File

@@ -0,0 +1,42 @@
#include <bits/stdc++.h>
using namespace std;
const int N = 10;
int n, m;
int res;
int dx[] = {2, 2, 1, -1, -2, -2, 1, -1};
int dy[] = {1, -1, 2, 2, 1, -1, -2, -2}; // 进行移动
bool st[N][N]; // 判断该数是否被标记过
// 马走日的回溯法实现
void dfs(int x, int y, int cnt) {
if (cnt == n * m) {
res++;
return;
}
for (int i = 0; i < 8; i++) {
int tx = x + dx[i], ty = y + dy[i];
if (tx < 0 || ty < 0 || tx >= n || ty >= m) continue;
if (st[tx][ty]) continue;
st[tx][ty] = 1;
dfs(tx, ty, cnt + 1);
st[tx][ty] = 0;
}
}
int main() {
int T;
cin >> T;
while (T--) { // 多组测试数据
res = 0;
memset(st, 0, sizeof st);
int x, y; // 初始位置坐标
cin >> n >> m >> x >> y;
st[x][y] = 1; // 标记起点
dfs(x, y, 1);
st[x][y] = 0; // 其实,出发点是否回溯无所谓,不会对其它人造成影响,而且,下一轮开始时有清空操作
cout << res << endl;
}
}

39
TangDou/AcWing/Dfs/TD.cpp Normal file
View File

@@ -0,0 +1,39 @@
#include <bits/stdc++.h>
using namespace std;
const int N = 10;
int g[N][N];
int st[N][N];
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};
int n, m, T;
int cnt;
int sx, sy, fx, fy;
void dfs(int x, int y) {
if (x == fx && y == fy) {
cnt++;
return;
}
for (int i = 0; i < 4; i++) {
int tx = x + dx[i], ty = y + dy[i];
if (tx <= 0 || ty <= 0 || tx > n || ty > m) continue;
if (st[tx][ty]) continue;
st[tx][ty] = 1;
dfs(tx, ty);
st[tx][ty] = 0;
}
}
int main() {
cin >> n >> m >> T;
cin >> sx >> sy >> fx >> fy;
while (T--) {
int x, y;
cin >> x >> y;
st[x][y] = 1;
}
st[sx][sy] = 1;
dfs(sx, sy);
cout << cnt << endl;
return 0;
}

View File

@@ -0,0 +1,39 @@
#include <bits/stdc++.h>
using namespace std;
const int N = 10;
int g[N][N];
int st[N][N];
int dx[] = {-1, 0, 1, 0}; // 上右下左
int dy[] = {0, 1, 0, -1}; // 上右下左
int n, m, T;
int cnt;
int sx, sy, fx, fy;
void dfs(int x, int y) {
if (x == fx && y == fy) {
cnt++;
return;
}
for (int i = 0; i < 4; i++) {
int tx = x + dx[i], ty = y + dy[i];
if (tx <= 0 || ty <= 0 || tx > n || ty > m) continue;
if (st[tx][ty]) continue;
st[tx][ty] = 1;
dfs(tx, ty);
st[tx][ty] = 0;
}
}
int main() {
cin >> n >> m >> T;
cin >> sx >> sy >> fx >> fy;
while (T--) {
int x, y;
cin >> x >> y;
st[x][y] = 1; // 标障碍点
}
st[sx][sy] = 1;
dfs(sx, sy);
cout << cnt << endl;
return 0;
}