[DFS] P1605 迷宫( 普及-)

本文详细解析了一道迷宫问题的DFS算法实现,通过递归位置、循环方向和回溯的策略,介绍了如何使用DFS算法寻找从起点到终点的所有路径。文章强调了输入处理的重要性,包括使用map函数定位障碍物和vis函数记录已访问位置,尤其指出起点标记的必要性,以避免重复计数。此外,还提供了具体代码实现,展示了如何通过数组存储方向并确保递归过程中的边界检查。

Date: 2019/10/10
Degree of difficulty:Universal
Original question:P1605 迷宫
在这里插入图片描述
又是一道dfs的题
这个题的思路就是——递归位置,循环方向,回溯——
我们来看看需要考虑的东西

  1. 输入
  2. 如何打表找位置
  3. 注意事项

1.输入

输入的时候需要借助一个map函数来帮助确定障碍的位置
还需要一个vis函数来记录走过的位置

起点需要打标记!!!!!!
(错误警告)
因为如果起点不打标记,那么后面的递归中,起点就会被重复利用好多次,有可能( 一定会 )多于你想要的结果
所以起点要打标记

2.如何打表找位置

打表找位置
说的简单就是用数组把方向存了
这个比较简单,显然
循环的时候也要注意一下不要越界

  • 弱鸡写法
int movx[5]={1,0,-1,0};
int movy[5]={0,-1,0,1};//打表找方向 
  • 有大佬把两个合了起来(interesting
int mov[6]={1,0,-1,0,1};
xx+= mov[i];
yy+= mov[i+1];

3.注意事项

没啥注意的,888
溜了溜了

AC code

//Author:PhilFan;
#include<bits/stdc++.h>
using namespace std;
int n,m,t,sx,sy,fx,fy,x,y,cnt;
int map[20][20],vis[20][20];
int movx[5]={1,0,-1,0};
int movy[5]={0,1,0,-1};//打表找方向 
void dfs(int x,int y){
	if(x == fx&& y == fy){
		cnt++;return ;//找到了就记录 
	} 
	int xx,yy;
	for(int i = 0; i <= 3; i ++){
		xx = x + movx[i];
		yy = y + movy[i];
		if(map[xx][yy]==0 && vis[xx][yy]==0 && xx>=1 && xx<=n && yy>=1 && yy<=n){
			vis[xx][yy]=1;
			dfs(xx,yy);
			vis[xx][yy]=0;//回溯 
		}
	}
}
int main()
{
	scanf("%d %d %d",&n,&m,&t);
	scanf("%d %d",&sx,&sy);
	scanf("%d %d",&fx,&fy);//输入 
	vis[sx][sy]=1;//	起点要标记的,因为如果不标记的话后面的答案会访问好几遍这个点
	//莫名奇妙多许多解的原因就在此 
	for(int i = 1; i <= t; i++){
		scanf("%d %d",&x,&y);
		map[x][y]=1;
	}
	dfs(sx,sy);
	printf("%d\n",cnt);
	return 0;
}

在计算机科学中,迷宫问题是经典的路径搜索问题之一,可使用图的深度优先搜索(DFS)来解决。具体方法如下: - **模型构建**:将迷宫表示为一个图,其中每个节点对应迷宫的一个位置,边代表两个位置之间可以通行的路径。例如定义一个二维数组 `N*M` 来表示迷宫,其中 `1` 表示墙壁,`0` 表示可以走的路,且只能横着走或竖着走,不能斜着走 [^1][^3]。 - **确定问题及参数**:明确迷宫的入口位置(如 `(x_1,y_1)`)和出口位置(如 `(x_2,y_2)`),根据问题需求,可能是寻找从入口到出口的路径,也可能是计算从入口到出口最多要走多少个格子等 [^2]。 - **DFS 搜索过程**:从入口开始进行深度优先搜索。在搜索过程中,每个单元格走完以后,要将走过的单元格置为已走。当单元格的位置与终点位置一致时,则代表已经到达终点,此时记录下该条路线的步数,然后回溯去找其他路线。注意,回溯时要将单元格置为未走,此时的单元格代表仍然可以走 [^4]。 以下是一个简单的 Python 代码示例,用于解决从迷宫左上角到右下角的路径问题: ```python def dfs(maze, x, y, path, visited): rows, cols = len(maze), len(maze[0]) # 判断是否越界、是否为墙壁或是否已经访问过 if x < 0 or x >= rows or y < 0 or y >= cols or maze[x][y] == 1 or (x, y) in visited: return False # 到达终点 if x == rows - 1 and y == cols - 1: path.append((x, y)) return True # 标记当前位置为已访问 visited.add((x, y)) path.append((x, y)) # 尝试四个方向 if dfs(maze, x + 1, y, path, visited) or dfs(maze, x - 1, y, path, visited) or \ dfs(maze, x, y + 1, path, visited) or dfs(maze, x, y - 1, path, visited): return True # 回溯 path.pop() return False # 示例迷宫 maze = [ [0, 1, 0, 0, 0], [0, 1, 1, 1, 0], [0, 0, 0, 0, 0], [0, 1, 1, 1, 0], [0, 0, 0, 1, 0] ] path = [] visited = set() if dfs(maze, 0, 0, path, visited): print("找到路径:", path) else: print("未找到路径") ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值