POJ—3984 迷宫问题 + 新手友好!

本文介绍了一种使用BFS(广度优先搜索)算法解决从二维数组迷宫的左上角到右下角的最短路径问题。通过记录路径、设置标志数组避免重复访问,并利用结构体存储节点信息,最终实现路径的打印。代码中详细解释了每个关键步骤,并提供了AC代码示例,适合新手理解。
摘要由CSDN通过智能技术生成

知识点 BFS + 记录路径
2021/1/28

题面来找到~~

定义一个二维数组:

int maze[5][5] = {

0, 1, 0, 0, 0,

0, 1, 0, 1, 0,

0, 0, 0, 0, 0,

0, 1, 1, 1, 0,

0, 0, 0, 1, 0,

};
它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。

--------------------------------------------分割线-------------------------------------------------------------

首先给出 AC 代码: 新手理解在后面!

#include<iostream>
#include<queue>
#include<cstring>
using namespace std;

char mp[10][10];
int x[4] = {0,1,0,-1};
int y[4] = {1,0,-1,0};
bool sg[6][6];
struct pt
{
	int x,y;
	int pre;
}now,tp,ans[100];
queue<pt> q;

void print(pt q)
{
	while(q.pre != -1)
	{
		print(ans[q.pre]); 
		cout << "(" << q.x << ","<<" "<<q.y<< ")" << endl;
		return ;
	}
	cout << "(" << 0 << ","<<" "<< 0 << ")" << endl;
}


void bfs()
{
	int f = 0,end = 0;
	memset(sg,false,sizeof(sg));
	pt r;
	r.x = 0;
	r.y = 0;
	r.pre = -1;
	q.push(r);
	end++;
	ans[0] = r;
	
	while(!q.empty())
	{
		now = q.front();
		q.pop();
		
		if(now.x == 4  && now.y == 4)
		{
			print(now);
			return ;
		}
		
		for(int i = 0; i < 4; i++)
		{
			int nx = now.x + x[i];
			int ny = now.y + y[i];
			
			if(nx < 0 || nx >= 5 || ny <  0 || ny >= 5) continue;
			if(mp[nx][ny] == '1' || sg[nx][ny]) continue;
			sg[nx][ny] = true;
			tp.x = nx;
			tp.y = ny;
			tp.pre = f;
			q.push(tp); 
			ans[end++] = tp;
		}
		f++;		
	}
}


int main()
{
	for(int i = 0; i < 5; i++)
		for(int j = 0; j < 5; j++)
			cin >> mp[i][j];
		
	bfs();
	return 0;
}

反思:
1.抛去记录路径这是一道BFS的模板题,没什么好说的;
2.如何记录路径呢?
先用数组记录路径,然后递归打印路径,具体操作如下

// 使用的结构体
struct pt // point
{
	int x,y;
	int pre; // 用来记录该点的前一个点;意思说使用数来表示一个点。。
}now,tp,ans[100]; // 结构体数组是用来访问点的!

tp.pre = f; // 用来存储该点上一个点的数,以用于后面访问改点的内容
ans[end++] = tp; // 在数组中存入该点信息;
//找到最短路径后,递归打印路径
void print(pt q)
{
	while(q.pre != -1)
	{
		print(ans[q.pre]); 
		cout << "(" << q.x << ","<<" "<<q.y<< ")" << endl;
		return ;
	}
	cout << "(" << 0 << ","<<" "<< 0 << ")" << endl;
}

根据Sample Input 来模拟该过程:
在这里插入图片描述

红色代表 f 在该点的值,粉色代表 end 在该点的值,同时由

tp.pre = f; // 用来存储该点上一个点的数,以用于后面访问改点的内容
ans[end++] = tp; // 在数组中存入该点信息;

end 就是 用来访问该点信息的:
因为是递归,会从终点直接递归到起点,如何找到前一个点,看图!
终点的 f 是13 即 终点 pre = 13; 那好

print(ans[q.pre]) 

ans【13】 的内容就是 终点的上一个点的 结构体!上一个点的结构体里存的pre = 10,则ans【10】 的内容就是它上一个点的结构体!!! 这样一直递归到 起点的前一个点 后面开始回溯
如果了解数组模拟队列的话,更好理解!!
建议过程去模拟一次,不要怕花时间!!
考虑不周之处希望能够指出!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值