比赛进行于2023年7月2日 本文写于7月3日早上
此比赛中主要是深搜的题目
深度优先搜索(DFS)是一种常用的图遍历算法,也可以应用于解决迷宫等问题。它探索图中的所有可能路径直到找到目标或无法继续探索为止。
深度优先搜索的基本思想是从起始节点开始,沿着一条路径尽可能深入地探索,直到无法继续下去,然后回溯到前一个节点,选择另一条路径继续探索,直到找到目标节点或遍历完整个图。
深度优先搜索的实现通常使用递归来处理,每次递归调用dfs函数来继续探索下一个节点。可以采用一个布尔数组来标记已访问的节点,避免重复访问和死循环。
需要注意的是,在迷宫问题中,我们还需要判断是否越界和是否为障碍物(例如墙壁)。根据具体情况,可能还需要记录路径以及其他辅助变量。
总结来说,深度优先搜索是一种探索图或树结构的常用方法,它通过递归地深入探索所有可能路径,并在满足条件时返回结果。对于初学者来说,理解DFS的基本原理并实现简单的示例代码是一个很好的起点,随着继续学习将能够应用于更复杂的问题。
好,下面来一起看例题
例题一:调理迷宫v1.0
A逃离迷宫1 |
时间限制 : 10000 MS 空间限制 : 65536 KB |
问题描述
有一个方格迷宫,我们可以将它看作一个n*m的矩阵,每个方格表示一个房间,方格中有数字0和1,数字0表示该房间是空的,可以顺利通过,数字1表示该房间有怪兽,不能通过。
一开始何老板位于左上角的方格(坐标[1,1]位置),他要走到右下角的出口(坐标[n,m]位置),每一步何老板只能往下或往右走。
他想知道总共有多少条可行的线路?
输入格式
第一行,两个整数n和m
接下来是一个有数字0和1构成的n*m的矩阵,表示迷宫
输出格式
一个整数,表示可行路线的条数。
样例输入
4 5
0 0 0 0 1
0 0 1 0 0
1 0 1 1 0
1 0 0 0 0
样例输出
3
提示
1<=n,m<=20
题解:
- #include <iostream>
- using namespace std;
- int Map[20][20];
- int Step[20][20];
- void FindWay(int x, int y, int dis, int a, int b) {
- if (dis < Step[x][y]) {
- Step[x][y] = dis;
- } else {
- return;
- }
- if (x == a && y == b) {
- return;
- }
- if (x + 1 <= a && Map[x + 1][y] == 0) {
- FindWay(x + 1, y, dis + 1, a, b); // 向下行走一步
- }
- if (y + 1 <= b && Map[x][y + 1] == 0) {
- FindWay(x, y + 1, dis + 1, a, b); // 向右行走一步
- }
- }
- int main() {
- int a, b;
- cin >> a >> b;
- for (int i = 0; i < a; i++) {
- for (int j = 0; j < b; j++) {
- cin >> Map[i][j];
- Step[i][j] = 100000;
- }
- }
- FindWay(0, 0, 0, a - 1, b - 1);
- cout << Step[a-1][b-1] << endl;
- return 0;
- }
例题二:逃离迷宫v2.0
B逃离迷宫2 |
时间限制 : 10000 MS 空间限制 : 65536 KB |
问题描述
有一个方格迷宫,我们可以将它看作一个n*m的矩阵,每个方格表示一个房间,方格中有数字0和1,数字0表示该房间是空的,可以顺利通过,数字1表示该房间有怪兽,不能通过。
一开始何老板位于左上角的方格(坐标[1,1]位置),他要走到右下角的出口(坐标[n,m]位置),每一步何老板可以往上、下、左、右走。
他想知道最少需要几步就可以走出迷宫?
输入格式
第一行,两个整数n和m
接下来是一个有数字0和1构成的n*m的矩阵,表示迷宫
输出格式
一个整数,表示最小步数。若无解,输出-1
样例输入
4 5
0 0 0 0 0
0 1 1 1 0
0 1 0 0 0
0 0 0 1 0
样例输出
7
提示
1<=n,m<=20
代码:
- #include <bits/stdc++.h>
- using namespace std;
- struct Point {
- int x;
- int y;
- int steps;
- };
- int escapeMaze(int n, int m, vector<vector<int>>& maze) {
- vector<vector<bool>> visited(n, vector<bool>(m, false));
- vector<int> dx = {-1, 1, 0, 0}; // 上下左右四个方向的x偏移量
- vector<int> dy = {0, 0, -1, 1}; // 上下左右四个方向的y偏移量
- queue<Point> q;
- q.push({0, 0, 0});
- visited[0][0] = true;
- while (!q.empty()) {
- Point curr = q.front();
- q.pop();
- if (curr.x == n-1 && curr.y == m-1) {
- return curr.steps;
- }
- for (int i = 0; i < 4; i++) {
- int nx = curr.x + dx[i];
- int ny = curr.y + dy[i];
- if (nx >= 0 && ny >= 0 && nx < n && ny < m && !visited[nx][ny] && maze[nx][ny] == 0) {
- q.push({nx, ny, curr.steps + 1});
- visited[nx][ny] = true;
- }
- }
- }
- return -1;
- }
- int main() {
- int n, m;
- cin >> n >> m;
- vector<vector<int>> maze(n, vector<int>(m));
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < m; j++) {
- cin >> maze[i][j];
- }
- }
- int steps = escapeMaze(n, m, maze);
- cout << steps << endl;
- return 0;
- }
更多题目,请见下文 sousousousousou考试分析(2)