题解 | #迷宫问题#

迷宫问题

https://www.nowcoder.com/practice/cf24906056f4488c9ddb132f317e03bc

现学的深搜算法解这道题,没想到运行时间是第一名,做这道题拖了很久,终于AC,发一篇题解庆祝一下。

分割线

——————————————————————————————————————————————————

主题:

深搜迷宫问题 求最短路径的详细走法

思路:

深搜 将路径存储在数组book中 求得最短路径长度时 现在的这个数组存储的路径就是最短路径的走法 将现在的最优可行解保存在ans数组中(这个过程好像有一个很高级的名字叫做保存现场) 最后等深搜函数结束运行之后 ans数组中存储的就是最短路径 只需要再次使用简单的深搜将ans数组中的路径走一遍并且打印出每个点的位置即可

代码实现:

//主题:深搜迷宫问题 求最短路径的详细走法 
//思路:深搜 将路径存储在数组中 求得最短路径长度时 现在的这个数组存储的路径就是最短路径的走法 
#include<bits/stdc++.h>
using namespace std;
//迷宫规模,迷宫,计算过程中存储路径的数组,存储最终结果的数组,最短路径长度
int n,m,a[11][11],book[11][11],ans[11][11],min_step=999;
void dfs(int row,int col,int step)//参数为当前所在行数,当前所在列数,当前走的步数
{
	if(row==n-1 && col==m-1){//到达右下角 
		if(step<min_step){
			min_step=step; 
		}
		//将当前最优可行解存储下来
		for(int i=0;i<n;i++){
			for(int j=0;j<m;j++){
				ans[i][j]=book[i][j];
			}
		}
		return;//如果到达了右下角就不用往下搜索了 
	}
	
	//没有到达右下角,继续往下一个点搜索
	int next[4][2]={
		{0,1},//向右走,行数不变,列数增加1 
		{1,0},// 向下走,行数增加1,列数不变 
		{0,-1},// 向左走,行数不变,列数减小1 
		{-1,0},// 向上走,行数减小1,列数不变 
	};
	int nr,nc;//next_row,next_column;下一个点的行数和列数 
	for(int i=0;i<=3;i++){
		nr=row+next[i][0];
		nc=col+next[i][1];
		if(nr<0 || nr>n-1 || nc<0 || nc>m-1){//越界 
			continue; 
		}
		if(a[nr][nc]==0 && book[nr][nc]==0){//该点是空地并且没有被走过 
			book[nr][nc]=1;//标记已走过,自断来路,以免回头 
			dfs(nr,nc,step+1);//开始尝试下一个点 
			book[nr][nc]=0;//将这个点置为0 
		}
	} 
	
	return; 
 } 
 void output(int row,int col){//深度优先方式输出ans数组中存储的路径 
 	if(row==n-1 && col==m-1){//到达右下角 
 		printf("(%d,%d)\n",row,col); //打印这一步的行列数,实际上就是右下角位置 
		ans[row][col]=0; //自断来路,避免回头
		return;
	}
	//没有到达右下角,继续往下一个点搜索
	int next[4][2]={
		{0,1},//向右走,行数不变,列数增加1 
		{1,0},// 向下走,行数增加1,列数不变 
		{0,-1},// 向左走,行数不变,列数减小1 
		{-1,0},// 向上走,行数减小1,列数不变 
	};
	int nr,nc;//next_row,next_column;下一个点的行数和列数 
	for(int i=0;i<=3;i++){
		nr=row+next[i][0];
		nc=col+next[i][1];
		if(nr<0 || nr>n-1 || nc<0 || nc>m-1){//越界 
			continue; 
		}
		if(ans[nr][nc]==1){//找到下一步的点 
			printf("(%d,%d)\n",row,col); //打印这一步的行列数
			ans[row][col]=0;//自断来路,避免回头 
			output(nr,nc); //以下一个点作为起点继续向下搜索 
			return;//注意这一个return很重要,在上一行,更深一层的递归结束之后
				   //这一层递归也应该结束了。 因为只要递归开始返回,就说明
				   //已经触达了终点,路径也已经打印出来了,所以不用再做任何操作,
				   //只需要结束这些递归函数的运行即可。	
		}
	} 
 }
int main(){
	cin>>n>>m;
	//book全部赋值为0	
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			book[i][j]=0;
		}
	} 	
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			cin>>a[i][j];
		}
	} 
	book[0][0]=1;//起点标注为1表示走过的
	dfs(0,0,0); //从0行0列出发,到达n-1行,m-1列,初始步数为0 
	output(0,0); //从左上角出发,深度优先方式将ans中路径打印出来 
	return 0;
}


#华为od##华为OD##华为##华为笔试##华为招聘#
全部评论
喔喔,我好像发现了一点点细节,这个运行时间很短有可能是多次提交,远程的评测机里面还有之前程序运行需要的一些内容,所以时间才这么短的。
点赞 回复 分享
发布于 2022-09-09 16:01 四川

相关推荐

点赞 评论 收藏
分享
屌丝逆袭咸鱼计划:心态摆好,man,晚点找早点找到最后都是为了提升自己好进正职,努力提升自己才是最关键的😤难道说现在找不到找的太晚了就炸了可以鸡鸡了吗😤早实习晚实习不都是为了以后多积累,大四学长有的秋招进的也不妨碍有的春招进,人生就这样
点赞 评论 收藏
分享
机械打工仔:有说的你怀疑一下就行了,直接问也太实诚了
点赞 评论 收藏
分享
评论
2
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务