以一道题目,作为介入点:
定义一个二维数组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; }