tianchai 12032 解救小哈(DFS或者BFS模版)

该博客主要介绍了如何利用深度优先搜索(DFS)或广度优先搜索(BFS)策略解决编号为12032的编程题目。内容涉及经典DFS模版的应用,并提供了相关代码实现。

题目描述(ID:12032)

标题: 解救小哈
详情: 有一天,小哈一个去玩迷宫。但是方向感很不好的小哈很快就迷路了。小哼得知后便立即去解救无助的小哈。小哼当然是有备而来,已经弄清楚了迷宫地图,现在小哼要以最快速度去解救小哈。问题就此开始了……
  迷宫由n行m列的单元格组成,每个单元格要么是空地,要么是障碍物。你的任务是帮助小哼找到一条从迷宫的起点到小哈所在位置的最短路径,注意障碍物是不能走的,当然也不能走到迷宫之外。n和m都小于等于100。
输入格式:
第一行有两个数N M。N表示迷宫的行,M表示迷宫的列。接来下来N行M列为迷宫,0表示空地,1表示障碍物。最后一行4个数,前两个数为迷宫入口的x和y坐标。后两个为小哈的x和y坐标。
输出格式:
一个整数表示小哼到小哈的最短步数。如果不能解救小哈则输出No Way!
提示: RQNOJ 34紧急援救
195校园迷宫
样例:

输入

5 4
0 0 1 0
0 0 0 0
0 0 1 0
0 1 0 0
0 0 0 1
1 1 4 3

输出

7

输入

3 3
1 1 1 
0 1 0 
0 1 0 
2 1 3 3

输出

No Way!

思路:

经典的DFS。


代码:

//DFS做法
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int minn=99999999;
int n,m,targetx,targety;
int a[101][101],book[101][101];

void dfs(int x,int y,int step)
{
	int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
	int dx,dy,k;
	if(x==targetx&&y==targety)
	{
		if(step<minn)
		minn=step;
		return ;
	}
	
	for(int k=0;k<4;k++)
	{
		dx=x+dir[k][0];
		dy=y+dir[k][1];
		if(dx<1||dx>n||dy<1||dy>m)continue;
		if(a[dx][dy]==0&&book[dx][dy]==0)
		{
			book[dx][dy]=1;
			dfs(dx,dy,step+1);
			book[dx][dy]=0;
	    }
	}
	return;
}


int main()
{
	freopen("in.txt","r",stdin);
    int startx,starty;
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=1;i<=n;i++)
	       for(int j=1;j<=m;j++)
	         scanf("%d",&a[i][j]);
	    scanf("%d%d%d%d",&startx,&starty,&targetx,&targety);
	    
	    book[startx][starty]=1;
	    dfs(startx,starty,0);
	    
	    if(minn==99999999)printf("No Way!\n");
	    else printf("%d\n",minn);	
    }

    return 0;
} 




//BFS模版
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<queue>
using namespace std;
const int INF=100000000; 
int n,m;
int a[101][101],d[101][101];
int sx,sy,gx,gy;  //起点和终点坐标 
typedef pair<int,int> P;

int bfs(){
	queue<P> que;
	//初始化所有位置 
	for(int i=0;i<n;i++)
		for(int j=0;j<m;j++)d[i][j]=INF;
	//将起点加入队列 
	que.push(P(sx,sy));
	d[sx][sy]=0;	
	
	int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};	
	
	while(que.size()){
		P p=que.front();que.pop();
		if(p.first==gx&&p.second==gy)break;
		
		for(int i=0;i<4;i++){
			int nx=p.first+dx[i],ny=p.second+dy[i];
			
			if(nx>=0&&nx<n&&ny>=0&&ny<m&&a[nx][ny]!=1&&d[nx][ny]==INF){
				que.push(P(nx,ny));
				d[nx][ny]=d[p.first][p.second]+1;
			}
		}
	} 
	return d[gx][gy];	
}


int main()
{
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++)
		for(int j=0;j<m;j++)
		{
			scanf("%d",&a[i][j]);
		}
	scanf("%d%d%d%d",&sx,&sy,&gx,&gy);  
	sx--;sy--;gx--;gy--;
	int res=bfs();
	if(res=100000000)puts("No Way!");
	else 	printf("%d\n",res);
	return 0;	
} 


<think>嗯,用户DFSBFS的实现模板。首先得确定他们需要的是基础的代码结构,可能是在准备面试或者学习算法。我需要先回忆一下这两种算法的基本框架。DFS通常用递归或者栈,而BFS用队列。根据用户提供的引用,比如引用[3]提到BFS的框架是起始点入队,循环处理队列,扩展队头元素。而DFS的话,引用[1]和[2]都提到DFS会尽可能深入,用递归或栈实现。 用户给的引用中有几个关键点,比如BFS的空间消耗较大,而DFS可能更节省空间但时间上可能有劣势。这些点可能在模板中体现出来。比如BFS需要用队列保存每一层的节点,而DFS递归时的隐式栈或者显式栈的结构。 需要确保模板代码正确,比如DFS的递归版本和迭代版本,BFS的标准队列操作。同时要注意注释说明,让用户明白每个步骤的作用。例如,在BFS模板中,是否需要标记已访问的节点?是的,特别是处理图的时候,避免重复访问。 然后,用户可能还需要一些注意事项,比如DFS在路径查找时的回溯步骤,或者BFS如何记录层数。引用[2]提到剪枝的重要性,这可能需要在模板之外进行优化,但模板本身应该保持简洁。 还要考虑不同应用场景下的变种,比如是否处理树或图的结构。例如,树的DFS可能不需要标记访问,但图的DFS必须标记,避免循环。因此,在模板中可能需要包含visited集合的部分。 最后,根据用户的要求,生成相关问题。可能需要围绕模板的使用、性能比较、应用场景来提问。例如,如何选择DFSBFS或者它们的时空复杂度分析。 总结下来,回答需要提供清晰的代码模板,区分递归和迭代实现,注明关键步骤,并附上相关问题帮助用户深入理解。</think>### DFSBFS算法模板代码解析 #### 1. 深度优先搜索(DFS)模板 DFS通过递归或栈实现“深度优先”特性,适用于路径查找、连通性检测等场景[^1]。 **递归实现模板**(以二叉树为例): ```python def dfs(node): if node is None: # 终止条件 return # 处理当前节点(例如打印或记录路径) print(node.val) # 递归访问相邻节点 dfs(node.left) dfs(node.right) ``` **迭代实现模板**(显式栈): ```python def dfs_iterative(root): stack = [root] visited = set() # 用于图结构防重复访问 while stack: node = stack.pop() if node not in visited: visited.add(node) # 处理当前节点 print(node.val) # 将子节点按反向顺序入栈(保证顺序正确) if node.right: stack.append(node.right) if node.left: stack.append(node.left) ``` #### 2. 广度优先搜索(BFS)模板 BFS通过队列实现“逐层扩展”特性,适用于最短路径、层级遍历等问题[^3]。 **标准模板代码**: ```python from collections import deque def bfs(root): queue = deque([root]) visited = set() # 用于图结构防重复访问 while queue: level_size = len(queue) for _ in range(level_size): # 按层处理(可选) node = queue.popleft() if node not in visited: visited.add(node) # 处理当前节点 print(node.val) # 将相邻节点加入队列 if node.left: queue.append(node.left) if node.right: queue.append(node.right) ``` #### 关键对比 | 特性 | DFS | BFS | |-----------|-------------------|-------------------| | 数据结构 | 栈(递归隐式栈/显式栈) | 队列 | | 空间复杂度 | $O(h)$(树的高度) | $O(w)$(树的宽度) | | 适用场景 | 路径存在性、拓扑排序 | 最短路径、层级遍历 |
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值