1、问题概述
ios
以前,咱们了解了如何实现迷宫问题(对于迷宫只有一个出口能够通的状况),事实上咱们的迷宫有多个出口,对于每条路径来讲,有长有短,因此在这里,咱们讨论一下迷宫的最短路径,即迷宫路径的最优解问题。spa
2、解决方案code
对于这样一个迷宫:blog
注:数字为0的表示能够经过,数字为1的表示不能够经过。
递归
从入口坐标:(2,0)开始,能够到达出口位置的通路总共有三条。可想而知,确定得把每一条路径都得遍历一遍,记录每条路径的长度。咱们这里采用了递归的思想。get
求解最短路径的办法:io
(1)将入口点标记起来,给其赋值;class
(2)每次访问的下一个位置就是前一个位置的值+1,直至一条路径成功通往出口;stream
(3)若是访问下一条路径的时候,递归会回退,在这里回退时它还会检测是否有通路,(上上节讲迷宫问题时有具体实现,能够去参照),这时因为咱们赋的值已经改变了,因此此时判断的条件为若是它的下一个位置的值+1>当前的位置的值,它就能够经过。遍历
(4)当每条路径走完后,会显示最后出口的值,这样就知道哪条路径最短啦。
图示以下:
3、实现代码
//Maze1.h
#include<iostream> using namespace std; #include<assert.h> #include<stack> struct Pos { int _row; int _col; }; void GetMaze(int *Maze,size_t N) { FILE* fout = fopen("Maze1.txt","r"); assert(fout); for(size_t i = 0; i < N; ++i) { for(size_t j = 0; j < N; ) { int value = fgetc(fout); if(value == '1' || value == '0') { Maze[i*N+j] = value - '0'; ++j; } else if(value == EOF) { cout<<"Maze error!"<<endl; return; } } } } bool IsCheckPath(int *maze,size_t n,Pos cur,Pos next) { if((next._row < 0 || next._row >= 10) || (next._col < 0 || next._col >= 10) ||(maze[next._row*n+next._col] == 1)) { return false; } if(maze[next._row*n+next._col] == 0) { return true; } return maze[next._row*n+next._col]+1 > maze[cur._row*n+cur._col]; } //递归 void GetMazePath(int *maze,size_t n,Pos entry,stack<Pos>& s,stack<Pos>& ss) { Pos cur; Pos next; s.push(entry); next = entry; if(entry._row == n-1) { if(ss.empty() || s.size() < ss.size()) { ss = s; } s.pop(); return; } //探测上下左右 //上 next = entry; cur = next; next._row-=1; if(IsCheckPath(maze,n,cur,next)) { maze[next._row*n+next._col] = maze[cur._row*n+cur._col]+1; GetMazePath(maze,n,next,s,ss); } //右 next = entry; cur = next; next._col+=1; if(IsCheckPath(maze,n,cur,next)) { maze[next._row*n+next._col] = maze[cur._row*n+cur._col]+1; GetMazePath(maze,n,next,s,ss); } //下 next = entry; cur = next; next._row+=1; if(IsCheckPath(maze,n,cur,next)) { maze[next._row*n+next._col] = maze[cur._row*n+cur._col]+1; GetMazePath(maze,n,next,s,ss); } //左 next = entry; cur = next; next._col-=1; if(IsCheckPath(maze,n,cur,next)) { maze[next._row*n+next._col] = maze[cur._row*n+cur._col]+1; GetMazePath(maze,n,next,s,ss); } //四方都不通 s.pop(); } void PrintMaze(int *maze,size_t n) { cout<<"迷宫显示:>"<<endl; for(size_t i = 0; i < n; ++i) { for(size_t j = 0; j < n; ++j) { cout<<maze[i*n+j]<<" "; } cout<<endl; } }
#include"Maze1.h" //用栈和递归实现迷宫问题 const size_t N = 10; void FunTest() { int Maze[N][N]; Pos entry = {2,0}; stack<Pos> ss; stack<Pos> ss1; GetMaze((int*)Maze,N); Maze[entry._row][entry._col] = 2; GetMazePath((int*)Maze,N,entry,ss,ss1); cout<<"迷宫是否有出口?"<<!ss.empty()<<endl; PrintMaze((int*)Maze,N); } int main() { FunTest(); return 0; }