简单迷宫问题的求解
作者:哪吒游戏网 来源:哪吒游戏网 2020-07-13 19:13:13
简单迷宫问题的求解,哪吒游戏网给大家带来详细的简单迷宫问题的求解介绍,大家可以阅读一下,希望这篇简单迷宫问题的求解可以给你带来参考价值。

假设这是一幅迷宫地图,‘0’表示通路,‘1’表示墙不能通过简单迷宫,‘entry’表示迷宫的入口。那么怎么从中找到出口呢?!这就是这篇文章要解决的问题。
一、思路:
我们可以利用回溯法的思想,也就是所谓的试探法:每走一步,我们都有上、下、左、右四个方向要去试探,如果该方向是‘0’,那么就继续向下走,并继续试探;否则退回一步简单迷宫,走另外一个方向…
此外,我们还要借助栈来存放走过的路径:向前走的时候每走一步将该位置push入栈,退回的时候pop退栈。
栈的模拟实现:点击打开链接
二、实现:
1.首先,我们需要从文件中读取数据(迷宫地图)
void InitMaze(int *a,int rows,int cols) //读取文件
{
FILE* pf =fopen("Maze.txt","r");
assert(pf);
for (int i=0; i<rows; i++)
{
for (int j=0; j<cols;)
{
char value = fgetc(pf);
if (value == '0' || value == '1')
{
a[i*N+j] = value-'0';
j++;
}
}
}
}
2.接下来就是找通路的问题了:
在这一部分主要的有三部分:a.表示位置的结构体b.判断此位置是否能通过的函数
c.最主要的一个函数——找通路
struct Pos
{
int _row;
int _col;
Pos(int rows = 0, int cols = 0)
:_row(rows)
,_col(cols)
{}
};
bool CheckAccess(int* maze,Pos pos) //判断当前位置是否是通路
{
if ((pos._row >= 0 ) && (pos._row < N)
&& (pos._col >= 0) && (pos._col < N)
&& (maze[pos._row*N+pos._col] == 0))
return true; //是通路
return false; //不是通路
}
void make_push(int* maze,Stack<Pos>& path,Pos pos) //将当前位置压入栈
{
path.Push(pos);
maze[pos._row*N+pos._col] = 2; //将走过的路径标记为2
}
bool chech_exit(int* maze, int rows,int cols,Pos pos) //判断是否走到出口
{
if ((pos._row == rows-1) || (pos._col == cols-1) || (pos._row == 0))
{
return true;
}
return false;
}
bool GetPath(int* maze, int rows,int cols,Stack<Pos>& path,Pos entry)
{
make_push(maze,path,entry); //入口标记为2
while(!path.Empty())
{
Pos cur = path.Top(); //每次读取栈顶的元素,即当前位置
Pos next = cur;
//上
next._row -= 1;
if (CheckAccess(maze,next))
{
make_push(maze,path,next);//将走过的路压入栈
continue;
}
next._row += 1;
//右
next._col += 1;
if (CheckAccess(maze,next))
{
make_push(maze,path,next);
continue;
}
next._col -= 1;
//下
next._row += 1;
if (CheckAccess(maze,next))
{
make_push(maze,path,next);
continue;
}
next._row -= 1;
//左
next._col -= 1;
if (CheckAccess(maze,next))
{
make_push(maze,path,next);
continue;
}
next._col += 1;
if (chech_exit(maze,rows,cols,next)) //判断出口
{
return true;
}
maze[cur._row*cols+cur._col]=3; //退栈时将回路标记为3,只是为了体现回溯的思想
path.Pop();
}
return false;
}
3.打印迷宫
void Ptintmaze(int *a,int rows,int cols) //打印迷宫
{
for (int i=0; i<rows; i++)
{
for (int j=0; j<cols;j++)
{
cout<<a[i*N+j]<<' ';
}
cout<<endl;
}
cout<<endl;
}
三、总体代码实现
#pragma once
#include "Stack.h"<span style="white-space:pre"> </span>//这里是自己实现的栈
const int N=10;
void InitMaze(int *a,int rows,int cols) //读取文件
{
FILE* pf =fopen("Maze.txt","r");
assert(pf);
for (int i=0; i<rows; i++)
{
for (int j=0; j<cols;)
{
char value = fgetc(pf);
if (value == '0' || value == '1')
{
a[i*N+j] = value-'0';
j++;
}
}
}
}
void Ptintmaze(int *a,int rows,int cols) //打印迷宫
{
for (int i=0; i<rows; i++)
{
for (int j=0; j<cols;j++)
{
cout<<a[i*N+j]<<' ';
}
cout<<endl;
}
cout<<endl;
}
struct Pos
{
int _row;
int _col;
Pos(int rows = 0, int cols = 0)
:_row(rows)
,_col(cols)
{}
};
bool CheckAccess(int* maze,Pos pos) //判断当前位置是否是通路
{
if ((pos._row >= 0 ) && (pos._row < N)
&& (pos._col >= 0) && (pos._col < N)
&& (maze[pos._row*N+pos._col] == 0))
return true; //是通路
return false; //不是通路
}
void make_push(int* maze,Stack<Pos>& path,Pos pos) //将当前位置压入栈
{
path.Push(pos);
maze[pos._row*N+pos._col] = 2; //将走过的路径标记为2
}
bool chech_exit(int* maze, int rows,int cols,Pos pos) //判断是否走到出口
{
if ((pos._row == rows-1) || (pos._col == cols-1) || (pos._row == 0))
{
return true;
}
return false;
}
bool GetPath(int* maze, int rows,int cols,Stack<Pos>& path,Pos entry)
{
make_push(maze,path,entry); //入口标记为2
while(!path.Empty())
{
Pos cur = path.Top(); //每次读取栈顶的元素,即当前位置
Pos next = cur;
//上
next._row -= 1;
if (CheckAccess(maze,next))
{
make_push(maze,path,next);//将走过的路压入栈
continue;
}
next._row += 1;
//右
next._col += 1;
if (CheckAccess(maze,next))
{
make_push(maze,path,next);
continue;
}
next._col -= 1;
//下
next._row += 1;
if (CheckAccess(maze,next))
{
make_push(maze,path,next);
continue;
}
next._row -= 1;
//左
next._col -= 1;
if (CheckAccess(maze,next))
{
make_push(maze,path,next);
continue;
}
next._col += 1;
if (chech_exit(maze,rows,cols,next)) //判断出口
{
return true;
}
maze[cur._row*cols+cur._col]=3; //退栈时将回路标记为3
path.Pop();
}
return false;
}
void test_mase()
{
int maze[N][N];
InitMaze((int*)maze,N,N);
Ptintmaze((int*)maze,N,N);
Stack<Pos> path;
cout<<"是否有通路?"<<GetPath((int*)maze,N,N,path,Pos(3,0))<<endl;
Ptintmaze((int*)maze,N,N);
}
运行结果:
总结:以上内容就是针对简单迷宫问题的求解详细阐释,如果您觉得有更好的建议可以提供给哪吒游戏网小编,简单迷宫问题的求解部分内容转载自互联网,有帮助可以收藏一下。
上一篇: 《一拳超人》闪光的佛莱士的过去,与音速的索尼克是这般关系
- 1 魔兽世界 考古(魔兽世界考古毁一生?这些装备幻化和坐骑值得你去玩考古)
- 2 普罗霍洛夫(卢布危机下俄土豪大甩卖 卖完豪宅卖球队)
- 3 龙之谷手柄(《龙之谷手游》手柄怎么连接 柄连接教学攻略)
- 4 普罗霍洛夫(俄罗斯土豪准备20亿抛售篮网! 最烂老板是怎样炼成的?)
- 5 天联网(天联网信息科技有限公司怎么样?)
- 6 附魔大师(魔兽世界怀旧服附魔大师在哪 附魔大师位置分享介绍)
- 7 wow烹饪食谱(魔兽世界怀旧服烹饪极品食谱)
- 8 陶谦让徐州(陶谦三让徐州,世界上真有这样的好人吗?)
- 9 lol神圣之剑(LOL如果神圣之剑回归,谁最受益?第1:只要不瞎都能上钻石!)
- 10 陶谦让徐州(陶谦三让徐州的原因是什么?)

机械战警
坦克射击
梦道满V版
火箭精英3d免费版
太古灵诀
小小帝国无敌破解版
厉害了我的娃
乐高无限
侠影双剑九游版