迷宫问题 Maze 4X4 (sloved by backtrack)
Description
给定一个N*N的迷宫中,(0,0)为起始点,(N-1,N-1)为目的地,求可通往目的地的多个解
思路
这道题其实就是简单的DFS,一路探索到底,没路就回溯到交叉口。
1 #include <iostream> 2 #include <vector> 3 #include <cstring> 4 using namespace std; 5 6 typedef struct 7 { 8 int x; 9 int y; 10 }pos; 11 12 #define N 4 //4*4 maze 13 #define ENTER_X 0 14 #define ENTER_Y 0 15 #define EXIT_X N-1 16 #define EXIT_Y N-1 17 18 int Maze[N][N]; 19 int paths; //sum of paths 20 vector<pos> Path; //svae paths 21 vector<pos> BestPath; //save min distant path 22 23 void InitMaze(); 24 bool MazeTrack(int x,int y); 25 26 int main() 27 { 28 InitMaze(); 29 int i = 0 , j = 0; 30 for(i=0;i<N;i++) 31 { for(j=0;j<N;j++) 32 cout << Maze[i][j]; 33 cout << endl; 34 } 35 MazeTrack(ENTER_X,ENTER_Y); 36 return 0; 37 } 38 39 void InitMaze() 40 { 41 int a[N][N] = { 42 {0,0,0,0}, 43 {1,0,1,0}, 44 {1,0,1,0}, 45 {1,0,1,0} 46 }; 47 memcpy(Maze,a,sizeof(a)); 48 paths = 0; 49 } 50 51 bool MazeTrack(int x,int y) 52 { 53 bool IsPath = false; 54 pos p; 55 p.x = x; 56 p.y = y; 57 //set range of maze's x/y 58 if(x<N && x>=0 && y<N && y>=0 && Maze[x][y]==0) 59 { 60 //make 61 Path.push_back(p); 62 Maze[x][y] = 1; //if value is 1,you can't go there 63 64 cout << "now,position is("<<x<<","<<y<<")" << endl; 65 //terminal 66 if(x==EXIT_X && y==EXIT_Y) 67 { 68 cout << "find a path" << endl; 69 paths++; 70 IsPath = true; 71 vector<pos>::iterator it; 72 for(it=Path.begin() ; it!=Path.end() ; it++) 73 cout << "("<< it->x <<","<< it->y <<")" << " "; 74 cout << endl; 75 return IsPath; 76 } 77 //search (find forward solutions) 78 IsPath = MazeTrack(x-1,y) || MazeTrack(x,y-1) || MazeTrack(x+1,y) || MazeTrack(x,y+1); 79 //backtrack 80 if(!IsPath) 81 { 82 Path.pop_back(); 83 Maze[x][y] = 0; 84 } 85 cout << Path.size() << endl; 86 } 87 //fuction exit 88 return IsPath; 89 }
输出的解:
0000 1010 1010 1010 now,position is(0,0) now,position is(0,1) now,position is(1,1) now,position is(2,1) now,position is(3,1) 4 3 2 now,position is(0,2) now,position is(0,3) now,position is(1,3) now,position is(2,3) now,position is(3,3) find a path (0,0) (0,1) (0,2) (0,3) (1,3) (2,3) (3,3) 7 7 7 7 7 7
我是第一次用回溯法,参考了下面的用回溯法解迷宫问题的模板:
1 using namespace std; 2 #define N 100 3 #define M 100 4 5 typedef struct 6 { 7 int x; 8 int y; 9 }Point; 10 11 vector<Point>solutionPath ; //存放有解的坐标路径 12 13 //主函数 x,y默认为起始结点,如(0,0), 得到从起始结点到目的结点的路径。 14 bool hasSolutionFunction( template<typename T>* Matrix , int x, int y) 15 { 16 17 bool *visited = new bool[M*N]; 18 memset (visited,0,M*N); //visited 存放每个结点是否被遍历,true为已经遍历过,false为否 19 20 res = hasSolutionCore(Matrix , x ,y) 21 cout<<solutionPath<<endl; 22 return res 23 24 } 25 26 //深度遍历求解路径的函数 27 bool hasSolutionCore(template<typename T>* Matrix , int x, int y) 28 { 29 30 hasSolution = false; 31 Point p = Point(x,y); 32 33 34 35 if (x,y) is terminal //x,y 已经是终止条件,当求解到这个结点是叶结点或目的地 36 { 37 solutionPath.push_back(p); 38 return true; 39 } 40 41 if ((x,y) && visited[x][y]==flase )// x,y是合法结点(具体条件可扩展),且未被访问过 42 { 43 visited[x][y] = true; 44 solutionPath.push_back(p); 45 46 hasSolution = hasSolutionCore(Matrix,x-1, y) ||hasSolutionCore(Matrix,x,y-1)||... //如果不是叶结点,则该路径是否有解取决于其他方向的往后求解。 47 48 // x,y结点以下的所有子路径都无解,则回溯 49 if (!hasSolution) 50 { 51 visited[x][y] = false; 52 solutionPath.pop_back(); 53 } 54 55 } 56 return hasSolution; 57 58 }
————全心全意投入,拒绝画地为牢