走出这个迷宫
来源:互联网 发布:区域经济考研知乎 编辑:程序博客网 时间:2024/04/30 17:12
求解迷宫路径是一个典型的问题,通常我们都是用 栈+回溯法+试探法 来解决这个问题。下面为大家介绍一下怎样用栈怎样找出迷宫的路径 。
在实现代码之前我们先来分下一下:
1、迷宫地图的设置
我们可以把迷宫地图存到文本里面,当需要的时候我们在重文本里面读取。因为迷宫的大小不确定,所以我们要动态开辟二维数组来存放地图。
如图:在第一行我们要存迷宫的
行 列 入口的横坐标 入口的纵坐标
接下来就是迷宫的地图。
2、如果当前坐标我们已经走过了,则要给予标记,也就是留下足迹。如果当前路径不通,那我们也要留下不通的标记。
3、求解路径的基本思想是:如果当前路径能通过,在将当前路径压栈,并做标记;然后回溯,读取下一个坐标再试探,如果不能通,则留下不能通过的标记,并把这个坐标出栈。
#define _CRT_SECURE_NO_WARNINGS#include<iostream>#include<cassert>using namespace std;typedef struct NodePos{int x;int y;NodePos(int row=0, int col=0):x(row), y(col){}}Node;//因为迷宫用的栈 是我自己的,为了方便验证,我将栈也给出template<typename T>class Stack{public:Stack():_capacity(0), _size(0), _ptr(NULL){}~Stack(){delete[] _ptr;_size = 0;_capacity = 0;_ptr = NULL;}void Push(const T& data);void Pop();T Top();int Size();bool Empty();private:void CheckCapacity(){if (_size >= _capacity){int NewCapacity = _capacity * 2 + 1;T* tmp = new T[NewCapacity];for (int i = 0; i < _size; i++){tmp[i] = _ptr[i];}delete[] _ptr;_ptr = tmp;_capacity = NewCapacity;}}private:T* _ptr;int _capacity;int _size;};template<typename T>bool Stack<T>::Empty(){if (_size == 0)return true;elsereturn false;}template<typename T>void Stack<T>::Push(const T& data){CheckCapacity();_ptr[_size++] = data;}template<typename T>void Stack<T>::Pop(){assert(_size>0);--_size;}template<typename T>T Stack<T>::Top(){return _ptr[_size - 1];}template<typename T>int Stack<T>::Size(){return _size;}//下面用到的栈是自己实现的栈template<typename T>class Maze{typedef Node Pos;public:Maze():_row(0), _col(0), _start(0,0), _map(NULL){}~Maze(){for (int i = 0; i < _row; i++){delete[] _map[i];}delete[] _map;}bool SearchPath(); //查找迷宫路径void PrintMap(); //输出迷宫地图void PrintPath(); //打印路径的坐标void SetMap(); //设置地图private:bool CheckNextAccess(Pos coor); //判断该坐标能否通过private:int _row;int _col;T **_map;Stack<Pos> _s;Pos _start;};template<typename T>bool Maze<T>::CheckNextAccess(Pos coor) //判断该坐标能否通过{if (coor.x >= 0 && coor.x < _row&&coor.y >= 0 && coor.y < _col&&_map[coor.x][coor.y] == 0) //判断是否越界{return true;}else{return false;}}template<typename T>void Maze<T>::SetMap(){char c;FILE *fp = fopen("MazeMap.txt", "r"); //打开文件读取地图assert(fp);//读取行while ((c = getc(fp))!= ' '&&c != '\n'){_row=_row*10+(c-'0');}//读取迷宫列while ((c = getc(fp)) != ' '&&c != '\n'){_col=_col*10+(c - '0');}//读取迷宫入口横坐标while ((c = getc(fp)) != ' '&&c != '\n'){_start.x = _start.x*10+(c - '0');}//读取迷宫入口纵坐标while ((c = getc(fp)) != ' '&&c != '\n'){_start.y = _start.y*10+(c - '0');}//开辟迷宫数组_map = new T*[_row];for (int i = 0; i < _row; i++){_map[i] = new T[_col];}//读取迷宫地图for (int i = 0; i < _row; i++){for (int j = 0; j < _col;){c = getc(fp);if (c == '1' || c == '0'){_map[i][j] = c - '0';j++;}}}fclose(fp); //关闭文件}template<typename T>bool Maze<T>::SearchPath(){Pos cur = _start;_s.Push(_start); //将起点坐标压入栈_map[_start.x][_start.y] = 2; //走过的路径设置为2while (!_s.Empty()) //如果栈以空,则说明又回到入口,则迷宫无解{Pos next=_s.Top();cur = next;_map[cur.x][cur.y] = 2; //将坐标设置为已走过if (next.x==_row-1||next.y==_col-1) //判断是否走到出口{return true;}//上next.x--;if (CheckNextAccess(next)) //如果当前坐标能够通过,则加入坐标{_s.Push(next);continue;}next.x++;//下next.x++;if (CheckNextAccess(next)){_s.Push(next);continue;}next.x--;//左next.y--;if (CheckNextAccess(next)){_s.Push(next);continue;}next.y++;//右next.y++;if (CheckNextAccess(next)){_s.Push(next);continue;}_s.Pop(); //如果当前坐标不通,则退栈_map[next.x][next.y]= 3; //并将这个坐标标记为不通}return false;}template<typename T>void Maze<T>::PrintMap() //打印迷宫地图,但是必须先设置迷宫地图{for (int i = 0; i < _row; i++){for (int j = 0; j < _col; j++){cout << _map[i][j] <<" ";}cout << endl;}}template<typename T>void Maze<T>::PrintPath() //打印迷宫路径{Stack<Pos> coor;while (!_s.Empty()){coor.Push(_s.Top());_s.Pop();}while (!coor.Empty()){cout << "(" << coor.Top().x << "," << coor.Top().y << ")" << endl;coor.Pop();}}void test(){Maze<int> m;m.SetMap(); //先设置地图m.PrintMap();cout << (m.SearchPath() == 1 ? "Yes":"NO") << endl;m.PrintMap();m.PrintPath();}int main(){test();system("pause");return 0;}
3 1
- 走出这个迷宫
- 走出迷宫
- 走出迷宫
- 走出迷宫
- 走出迷宫
- 走出 JNDI 迷宫
- 走出迷宫 Maze
- 走出 JNDI 迷宫
- 【NOI】6264 走出迷宫
- java 蓝桥杯 走出迷宫
- 6264:走出迷宫
- 走出资金管理的迷宫
- 走出ClassLoader的迷宫[翻译]
- 走出迷宫小游戏v1.5
- 走出迷宫小游戏的实现
- [OpenJudge-NOI]走出迷宫 Bfs
- [OpenJudge-NOI]走出迷宫 Bfs
- 走出类加载器迷宫
- 十二章上机 练习4
- pat乙1027. 打印沙漏
- ButterKnife使用
- BNU20409 UVA11991
- jQuery append动态添加的元素添加事件没有效果
- 走出这个迷宫
- C++Primer(第四章课后习题)(程序题源代码)
- CentOS 无密码 ssh 登陆
- Hibernate 带in参数的写法
- 怎样隐藏导航状态栏NavigationBar
- iOS 隐藏导航栏底部线的两种方法
- git pull出错fatal:Please make sure you have the correct access rights.and the repository exists.
- html中<img>标签的路径问题
- poj2632 Crashing Robots