问题描述
东东有一张地图,想通过地图找到妹纸。地图显示,0表示可以走,1表示不可以走,左上角是入口,右下角是妹纸,这两个位置保证为0。既然已经知道了地图,那么东东找到妹纸就不难了,请你编一个程序,写出东东找到妹纸的最短路线。
在本问题中,(1)迷宫是5*5,即二维数组是5行5列(2)仅由0,1组成
【输入】
一个5*5的二维数组,仅由0,1两数字组成,表示法阵地图
【输出】
输出若干行,表示从左上角到右下角的最短路径依次经过的坐标
【输入样例】
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
【输出样例】
(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)
问题分析
本文图,给出起点,终点和可走路径,主要是搜素问题,常见解决方式有bfs广度优先搜索和dfs深度优先搜索,求最短路径一般选用bfs,dfs求最短路径只能是把所有可能到目的地的方法所需步数都比较一下,保存最小的那个值,所有解都遍历一遍,才能得出最优解。
输出遍历点的顺序,用bfs解题,使用队列结构存储路径,一个可走点上下左右四个点,不是障碍点或已走点就入队,直到判断到达终点,同时使用pre数组来记录每个节点入队前的前驱节点以便倒序输出。
代码
#include<iostream>
#include<queue>
using namespace std;
struct node
{
int x,y;
};
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};//临近的四个点右左上下
int vis[5][5];//vis用来标记是否走过该点
int mark[5][5];//障碍点
node pre[5][5];//每个节点的前驱节点
void out(node tail)
{
if(tail.x==0&&tail.y==0)
{
cout<<"(0, 0)"<<endl;
return;
}
out(pre[tail.x][tail.y]);//逆序输出
cout<<"("<<tail.x <<", "<<tail.y<<")"<<endl;
}
void BFS()
{
vis[0][0]=1;//已走过的点
queue<node> que;
node point;
point.x=point.y=0;
que.push(point);
while(!que.empty())
{
node now=que.front();
que.pop();
if(now.x==4&&now.y==4) return;//到达终点
for(int i=0;i<4;i++)
{
node next;
next.x=now.x+dir[i][0];
next.y=now.y+dir[i][1];
if(next.x>=0&&next.x<=4&&next.y>=0&&next.y<=4)//边界条件
{
if(!mark[next.x][next.y]&&!vis[next.x][next.y]) //判断障碍物设置和是否走过该点
{
vis[next.x][next.y]=1;//该点在路径范围内
que.push(next);
pre[next.x][next.y]=now;
}
}
}
}
}
int main()
{
for(int i=0;i<5;i++)
for(int j=0;j<5;j++)
cin>>mark[i][j]; //输入障碍点
BFS();
node tail;
tail.x=tail.y=4;
out(tail);
}