编程语言
首页 > 编程语言> > 程序作业week02-A题

程序作业week02-A题

作者:互联网

A-Maze
题目
在这里插入图片描述样例

Sample Input
0 1 0 0 0
0 1 0 1 0
0 1 0 1 0
0 0 0 1 0
0 1 0 1 0

Sample Output
(0, 0)
(1, 0)
(2, 0)
(3, 0)
(3, 1)
(3, 2)
(2, 2)
(1, 2)
(0, 2)
(0, 3)
(0, 4)
(1, 4)
(2, 4)
(3, 4)
(4, 4)

在这里插入图片描述

解题思路

这是一个经典的迷宫题(四连通),搜索路径问题可以用dfs也可以用bfs。这道题目的要求是求出找妹纸的最短路径,bfs一层一层地搜索最先找到终点的路径就是最短的,如果用dfs的话要找到所有解进行选择,所以我在这里采用bfs的方法。

定义mp数组存地图,vis数组用于判断结点是否被访问过,初始化为全0表示最开始没有被访问过。定义结构体node存储节点的坐标信息,大小也是5*5.然后定义一个node类型的队列,在bfs中记录节点。

int mp[5][5];
int vis[5][5];
struct node
{
	int x, y;
};
node pre[5][5];
queue<node> q;

广度优先搜索bfs()
这里就是普通的广度优先搜索

先将起点(0,0)入队列,并标记,即vis[0][0]=1.
然后进入循环,取出队首并记为p,然后pop该节点

搜索该节点的四个可到达的节点,这里搜索采用循环的方式,让坐标加上-1或0或1.因为只有上下左右四个方向,所以要增加一个约束,x、y的增加量之和要么是1,要么是-1.这样就可以剔除斜着四个方向和原地不动的情况

遍历这四个节点时,要判断是否为有效点,判断是否坐标越出地图范围,以及该点是否被访问过,即vis值是否为1.

如果是可以访问的节点,就加入队列中,并标记vis为1,用pre记录新加入节点的前一个节点(相当于爸爸qwq),以便于后面输出路径


```cpp
for(int i=-1;i<2;i++)
		{
			for(int j=-1;j<2;j++)
			{
				node nn;
				nn.x = p.x+i;
				nn.y = p.y+j;
				if(i+j==1||i+j==-1)
				{
					if((nn.x<0||nn.x>4||nn.y<0||nn.y>4)||vis[nn.x][nn.y]==1||mp[nn.x][nn.y]==1)
					continue;
					q.push(nn);
					vis[nn.x][nn.y] = 1;
					pre[nn.x][nn.y] = p;
				}
			}
		}

循环直至队列为空(其实想到这个题目里在循环末尾可以加一个判断,如果找到终点(4,4)就停止搜索清空队列来着。。。因为第一次遇见终点就是最短路径了qwq写的时候没多想)

输出路径track()

因为在广搜时记录了节点的前一个节点,在输出路径时通常有两种方法:一是从终点往前推,把一路上的节点都存在一个数组里,最后逆序输出;另一个就是递归方法,从终点开始不停递归上一个节点,直到递归函数的参数是起点,返回上一层输出。两种方法都可,在这里我用的是递归。


```cpp
void track(node pp)
{
	if(pp.x==0&&pp.y==0)
	{
		cout<<"(0, 0)"<<endl;
		return;
	}
	track(pre[pp.x][pp.y]);
	cout<<'('<<pp.x<<", "<<pp.y<<')'<<endl;
}

完整代码


```cpp
#include <iostream>
#include <queue>
using namespace std;

int mp[5][5];
int vis[5][5];
struct node
{
	int x, y;
};
node pre[5][5];
queue<node> q;

void bfs()
{
	node p;
	p.x = 0;	p.y = 0;
	q.push(p);	
	vis[0][0] = 1;
	while(!q.empty())
	{
		p = q.front();
		q.pop();
		for(int i=-1;i<2;i++)
		{
			for(int j=-1;j<2;j++)
			{
				node nn;
				nn.x = p.x+i;
				nn.y = p.y+j;
				if(i+j==1||i+j==-1)
				{
					if((nn.x<0||nn.x>4||nn.y<0||nn.y>4)||vis[nn.x][nn.y]==1||mp[nn.x][nn.y]==1)
					continue;
					q.push(nn);
					vis[nn.x][nn.y] = 1;
					pre[nn.x][nn.y] = p;
				}
			}
		}
	}
}
void track(node pp)
{
	if(pp.x==0&&pp.y==0)
	{
		cout<<"(0, 0)"<<endl;
		return;
	}
	track(pre[pp.x][pp.y]);
	cout<<'('<<pp.x<<", "<<pp.y<<')'<<endl;
}
int main()
{
	for(int i=0;i<5;i++)
	{
		for(int j=0;j<5;j++)
		{
			cin>>mp[i][j];
			vis[i][j] = 0;
		}
	}
	bfs();
	node end;
	end.x = 4;	end.y = 4;
	track(end);
	return 0;
}
Wake up 发布了1 篇原创文章 · 获赞 0 · 访问量 24 私信 关注

标签:week02,node,nn,int,作业,程序,bfs,vis,节点
来源: https://blog.csdn.net/wakeupshely/article/details/104605364