Maze迷宫问题(最优解)

迷宫地形我们可以通过读文件的形式,通过已知入口逐个遍历坐标寻找通路。

文件如图:

wKiom1cSCnTB8pO4AAAZiAM5LuE146.png

每个坐标的位置用结构体来记录:

struct Pos    //位置坐标
{
   int  _row;
   int _col;
};

定义行列范围

#define M 10   //行
#define N 10   //列

初始化迷宫数组
将通过读文件的方式获取的字符转成整型数据,保存在M行N列的数组中。

void InitMaze(int* maze)
{	
	struct WavHeadhWAV;
	FILE* fout = fopen("MazeMap.txt", "r");   // .txt文件要放在当前目录下
	if (fout == NULL)                       // 这里一定要检查读文件是否成功
	{
		cout << "can't find MazeMap.txt !" << endl<<endl;
		return;
	}
	for (int i = 0; i < M; i++)
	{
		for (int j = 0; j < N;)
		{
			char ch = fgetc(fout);
			if (ch=='1'||ch=='0')
			{
				maze[i*N + j] = ch - '0';
				j++;
			}
		}
	}
	fclose(fout);
}

回溯查找通路

利用栈来存储通路,通过上下左右四个方向依次遍历,如果该位置满足条件,就将它入栈,并将该位置的数据置为2;如果四个方向都不满足条件就执行出栈操作,回溯查找满足条件的位置(这时候如果栈为空了,说明查找通路失败),继续循环遍历,直到找到出口为止。

这里建立一个最小栈,如果找到出路,就将该栈赋给最小栈,并将出口置为1,继续回溯查找通路,如果又一次找到通路,就将该栈的长度与最小栈进行比较,如果该栈长度比最小栈还要小,就将它再一次赋给最小栈(保证最小栈是最短的通路),继续回溯,直到整个栈为空,回到了入口,程序结束。

bool SearchMazePath(int *maze, Pos entry, stack<Pos>& paths)   // 利用栈回溯查找通路,并实现迷宫的最优解
{
	assert(maze);
	stack<Pos>min;
	paths.push(entry);
	while (!paths.empty())
	{
		Pos cur = paths.top();
		maze[cur._row*N+cur._col] = 2;
		if (cur._row==M-1)
		{
			if (paths.size()< min.size() || min.size() == 0)
			{
				min = paths;
			}
			paths.pop();
			maze[min.top()._row*N + min.top()._col] = 1;
		}	
		Pos next = cur;
		next._col--;  //左
		if (CheckIsAccess(maze, next))
		{
			paths.push(next);
			maze[next._row*N + next._col] = 2;
			continue;
		}
		next = cur;
		next._col++; //右
		if (CheckIsAccess(maze, next))
		{
			paths.push(next);
			maze[next._row*N + next._col] = 2;
			continue;
		}
		next = cur;
		next._row--; //上
		if (CheckIsAccess(maze, next))
		{
			paths.push(next);
			maze[next._row*N + next._col] = 2;
			continue;
		}
		next = cur;
		next._row++; //下
		if (CheckIsAccess(maze, next))
		{
			paths.push(next);
			maze[next._row*N + next._col] = 2;
			continue;
		}
		paths.pop();
	}
	if (paths.empty()&&!min.empty())
	{
			maze[min.top()._row*N + min.top()._col] = 2;
			return true;
	}
	return false;
}

检查该位置是否合法:(坐标在行列范围之内)

bool CheckIsAccess(int* maze, const Pos& next)    // 检查该位置是否合法
{
	assert(maze);
	if ((next._row >= 0 && next._row <= N) && (next._col >= 0 && next._col < M) && maze[next._row*N + next._col] == 0)
	{
		return true;
	}
	return false;
}

打印迷宫:

void PrintMaze(int *maze)   // 打印迷宫
{
	assert(maze);
	for (int i = 0; i < M; i++)
	{ 
		for (int j = 0; j < N; j++)
		{
			cout << maze[i*N + j] <<" " ;
		}
		cout << endl;
	}
	cout << endl;  
}

wKioL1cSXnWRU9roAAAG8lMrhuE483.png

本文出自 “言安阳” 博客,谢绝转载!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值