以一道题目,作为介入点:
定义一个二维数组N*M(其中2<=N<=10;2<=M<=10),如5 × 5数组下所示:
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表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。入口点为[0,0],既第一空格是可以走的路。
Input
一个N × M的二维数组,表示一个迷宫。数据保证有唯一解,不考虑有多解的情况,即迷宫只有一条通道。
Output
左上角到右下角的最短路径,格式如样例所示。
Sample Input
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
Sample Output
(0, 0)
(1, 0)
(2, 0)
(2, 1)
(2, 2)
(2, 3)
(2, 4)
(3, 4)
(4, 4)
输入描述:
输入两个整数,分别表示二位数组的行数,列数。再输入相应的数组,其中的1表示墙壁,0表示可以走的路。数据保证有唯一解,不考虑有多解的情况,即迷宫只有一条通道。
输出描述:
左上角到右下角的最短路径,格式如样例所示。
示例1
输入
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
输出
(0,0)
(1,0)
(2,0)
(2,1)
(2,2)
(2,3)
(2,4)
(3,4)
(4,4)
想必这种题目,大家都很熟悉,走迷宫!
让我们来整理下,怎么来进行迷宫的行走:
1.从左上角定点(0,0)开始,将起始点加入到栈S;
2.弹出栈S的顶层结点,判断是否已经到达终点(4,4);
3.未到达终点,取出他的相邻结点,条件:相邻的结点不为1(1代表墙),结点不越界,所以取出(1,0)加入栈Q;
4.关键点来了,如果取到一个相邻结点里面退出继续循环,则采用的是DFS,如果直到取完所有的相邻结点再继续循环则是BFS;
5.我们先采用DFS的方式,取完一个就继续循环,重复2的步骤;
看下源码:
#include "stdafx.h"
#include <iostream>
#include <stack>
using namespace std;
//这种迷宫题的难点在于,输出一条路径
typedef struct _Point
{
int x;
int y;
_Point()
{
x = 0;
y = 0;
};
_Point(const int& v_nx, const int& v_ny)
{
x = v_nx;
y = v_ny;
};
bool operator==(const _Point& v_p)
{
if(x == v_p.x && y == v_p.y)
{
return true;
}
return false;
}
}POINT, *PPOINT;
int main()
{
int MyMap[10][10] = {0};
//地图
int M, N = 0;
int dir[4][2] = {{0, 1},{1, 0},{0, -1},{-1, 0}};
while(cin >> N >> M)//N行M列
{
for(int i = 0; i < N; ++i)
{
for(int j = 0; j < M; ++j)
cin >> MyMap[i][j];
}
int MyVisit[10][10] = {0}; //用数组标识是否已经访问过
//设置起始点
POINT pointStart;
pointStart.x = 0;
pointStart.y = 0;
//设置终点
POINT pointEnd;
pointEnd.x = N - 1;
pointEnd.y = M - 1;
stack<POINT> Queue;
bool bFind = false;
//首先将起点加入队列
Queue.push(pointStart);
MyVisit[pointStart.x][pointStart.y] = 1;
while(!Queue.empty())
{
//取出结点
POINT pointCur = Queue.top();
if(pointCur == pointEnd) //遍历到终点了
{
bFind = true;
break;
}
//计算相邻节点
for(int i = 0; i < 4; ++i)
{
POINT pointNext(pointCur.x + dir[i][0], pointCur.y + dir[i][1]);
//判断这个Next节点是否有效:是否越界,是否不是一堵墙
if(pointNext.x >= 0 && pointNext.y >= 0 && pointNext.x < N && pointNext.y < M && MyMap[pointNext.x][pointNext.y] == 0)
{
if(MyVisit[pointNext.x][pointNext.y] == 0)//判断节点是否访问过
{
Queue.push(pointNext);
MyVisit[pointNext.x][pointNext.y] = 1;
break; //找到一个立马去找下一个,采用深度优先搜索的方式
}
}
}
if(!bFind)
{
continue;
}
else //如果最终未找到,则弹出这个结点,查找上一个结点,以此类推
{
Queue.pop();
}
}
if(!Queue.empty())
{
stack<POINT> tmp;
while(!Queue.empty())
{
tmp.push(Queue.top());
Queue.pop();
}
while(!tmp.empty())
{
cout << "(" << tmp.top().x << "," << tmp.top().y << ")" << endl; tmp.pop();
}
}
else
{
cout << "No Find One Path!" << endl;
}
}
return 0;
}