例题一:迷宫问题
有一天,傻子A一个人去迷宫玩,但是他的方向感并不是很好,所以他很快就迷路了,哎哟喂,这可把他的小伙伴小Z给急死了,小Z得知后立即去解决傻子A,小Z来之前,做足了调研,弄到了迷宫的地图,现在问题来了:小Z要用最快的速度去解救傻子A。小Z拥有的地图是一个n行m列的单元格(0< n , m <= 50),单元格上要么是空地,要么是障碍物,我们的任务是帮小Z找一条从迷宫起点,通往小Z所在位置的最短路径,注意:障碍物时不能走的!小A时不动的,规定0表示空地、1表示障碍物。
样例输入:
5 4
0 0 1 0
0 0 0 0
0 0 1 0
0 1 0 0
0 0 0 1
1 1 4 3(前两个为小Z所在位置坐标、后两个是傻子A所在位置)
样例输出:
7
思路:二维数组处理地图,一个pair组存储坐标、再来一个pair组存储坐标和该坐标的步数。
一个队列当作容器。一个bool型数组处理已走过的地点,一个flag标志是否走到目标处。在最后输出队列的尾元素。
代码表示:
#include<iostream>
#include<queue>
#define MAXN 51
using namespace std;
typedef pair<int,int> loc; //存储坐标
typedef pair<loc,int> point; //存储坐标和步数
queue<point> que; //队列
int map[MAXN][MAXN];
bool book[MAXN][MAXN]={false};
int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
int n,m;
int main()
{
cin >> n >> m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin >> map[i][j];
int sx,sy,ex,ey;
cin >> sx >> sy >> ex >> ey ;
point p,p1;
p.first.first=sx; //point的第一个元素的第一个元素被赋值为sx
p.first.second=sy; //同上
p.second=0;
que.push(p);
book[sx][sy]=true;
bool flag=false; //表示没有找到目标点
//队列不为空时,执行下列操作
while(!que.empty())
{
p=que.front();
que.pop();
//枚举四个方向
for(int i=0;i<4;i++)
{
int gx=p.first.first+next[i][0];
int gy=p.first.second+next[i][1];
//判断是否越界
if(gx<1||gx>n||gy<1||gy>m)
continue;
//判断是否为障碍物或者已经在路径中
if(map[gx][gy]==0&&book[gx][gy]==false)
{
//标记这个点已经被走过
//宽搜每个点只入队一次,不需将book数组还原
book[gx][gy]=true;
p1.first.first=gx;
p1.first.second=gy;
p1.second=p.second+1; //父亲步数加一
que.push(p1);
}
//达到目标点停下来
if(gx==ex&&gy==ey)
{
flag=true;
break;
}
}
if(flag)
break;
}
//打印队列末尾最后一个点(目标点)的步数
p1=que.back();
cout << p1.second << endl;
return 0;
}