BFS解决迷宫问题,第二种方式,代码差不多但是更简单

受这个视频启发:

BFS广搜解决迷宫问题_哔哩哔哩_bilibili

地图上各个坐标点距离起点的depth直接封装在Pos里面就可以了,省得还要建一个二维矩阵对应地图上每个点的depth。

而且,不需要用来之前那个定理一,因为BFS搜索到终点的时候,路径一定是最短的。因为BFS是一层一层往外扩张的,不是一条路走下去的。

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

const int MAX_SIZE = 25;
const int INF_INT = 0x3f3f3f3f;

//用点来走迷宫,有面向对象那味,比较好写。如果单纯记录坐标,就很不直观,变量会很多。
struct Pos
{
	int x, y;
	int depth;
	//关系运算符重载,判等
	bool operator == (const Pos& rhs) const
	{
		return x == rhs.x && y == rhs.y;
	}
	bool operator != (const Pos& rhs) const
	{
		return !(*this == rhs);
	}
};

//判断是否跑出边界
bool inside_judge(const Pos& pos, int n, int m)
{
	return 0 <= pos.x && pos.x < n && 0 <= pos.y && pos.y < m;
}

int bfs(const Pos& src, const Pos& sink, int n, int m, int maze[][MAX_SIZE])
{
	const int dir[4][2] = { {-1, 0}, {0, -1}, {1, 0}, {0, 1} };     //定义四个方向  也可以写两个一维数组,只要能实现改变横纵坐标就行
	queue<Pos> que;            //广度优先的那个队列,起始点入栈
	que.push(src);
	int Is_visit[100][100];
	memset(Is_visit, 0, sizeof(Is_visit));   //把是否已访问都置为0
	while (!que.empty())
	{
		Pos now = que.front();
		que.pop();
		if (now == sink)              //重载的==
		{
			return now.depth;     //即最短路径
		}
		//没到终点就继续搜索,广度优先,4次循环,四个方向都走一格,每走一格都计算一下附近的最短路径。而不是往一个方向钻。
		//只要能走,就给他走一下
		for (int ind = 0; ind < 4; ++ind)
		{
			Pos next = now;
			next.x += dir[ind][0];          //设定下一个的坐标,有向上下左右4种可能,都改变一下坐标看看有没有越界、是不是0
			next.y += dir[ind][1];          //dir[4][2] = { {-1, 0}, {0, -1}, {1, 0}, {0, 1} }; 
											//dir[4][2]的顺序为【左上右下】,所以一开始往下走,dp[0][-1]=1,然后(0,-1)这个点入队列
											//然后回来,再初始化next结点为now,再往右走,dp[1][0]=1,然后(1,0)这个点入队列。
											//然后这个for循环就结束了,回到while循环,判断队列不空,拿到队首元素(0,-1),继续上述操作
			/* 2 0 0
			   0 0 1
			   3 0 1*/       //这就是maze的本尊
			if (inside_judge(next, n, m) && Is_visit[next.x][next.y] == 0 && maze[next.x][next.y] == 0)
			{
				Is_visit[next.x][next.y] = 1;
				next.depth = now.depth + 1;
				que.push(next);
			}
		}
	}
	return -1;       //如果在上面没能return成功,就出while循环,返回-1
}

void incubate()
{
	int n, m;
	int maze[MAX_SIZE][MAX_SIZE];
	/* 2 0 0
	   1 0 1
	   3 0 1*/         //maze填入数据后,就长这样
	Pos src, sink;                     //起点和终点
	int ans;
	while (cin >> n >> m)              //这是什么骚操作?
	{
		for (int i = 0; i < n; ++i)
		{
			for (int j = 0; j < m; ++j)
			{
				cin >> maze[i][j];
			}
		}
		for (int i = 0; i < n; ++i)
		{
			for (int j = 0; j < m; ++j)
			{
				switch (maze[i][j])         //寻找起始和终点
				{
				case 2: src.x = i, src.y = j, src.depth = 0, maze[i][j] = 1;
					break;

				case 3: sink.x = i, sink.y = j, maze[i][j] = 0;
					break;

				default:
					break;
				}
			}
		}
		ans = bfs(src, sink, n, m, maze);
		if (-1 == ans)
		{
			cout << "Disconnected!" << endl;
		}
		else
		{
			cout << "The miminum distance from start point to target point is"
				<< ans << endl;
		}
	}
	return;
}
int main(int argc, char* argv[])
{
	incubate();
	return 0;
}

/*
测试数据:
connected
3 3
2 0 0
1 0 1
3 0 1
connected
3 3
2 0 0
0 0 1
3 0 1
disconnected
3 3
2 0 0
1 1 1
3 0 1
 */

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值