栈的应用之迷宫问题

走迷宫的规则:

当前坐标是(i, j)下一步可以往四个方向行走,上下左右。在迷宫数组 0标识可以走,1标识不能走 2 标记已经走过 3标识回退的路

穷举法走出迷宫有两种方法:

方法一:用栈模拟

具体思路:

当遇到地图的位置为0时,表示此位置可以透过,将其位置的值由0变为i,并进行压栈处理,将此位置保存,以便此路径不通时进行回溯。假如某位置的上下左右都不通时,将此位置标记为3(表示已经走过此位置),并进行弹出操作。假如到了边界位置,则表示走出迷宫。若回溯到了迷宫的入口,则表示迷宫没有出口。

代码如下:

struct Pos
{
	int _row;
	int _col;
};

void GetMaze(int* a, int n)
{
	assert(a);
	FILE* fout = fopen("MazeMap.txt", "r");
	assert(fout);
	for (int i = 0; i < n; ++i)
	{
		for (int j = 0; j < n; )
		{
			char ch = fgetc(fout);
			if (ch == '1' || ch == '0')
			{
				a[i*n + j] = ch - '0';
				++j;
			}
		}
	}
}


void PrintMaze(int* a, int n)
{
	for (int i = 0; i < n; ++i)
	{
		for (int j = 0; j < n; ++j)
		{
			cout << a[i*n + j]<<" ";
		}
		cout << endl;
	}
	cout << endl;
}


bool CheckIsAccess(int* a, int n, const Pos& next)
{
	int  row = next._row;
	int col = next._col;
	if (row >= 0 && row < n
		&&col >= 0 && col < n
		&&a[row*n + col] == 0)
	{
		return true;
	}
	else
	{
		return false;
	}
}

bool SearchMazeSize(int* a, int n, Pos entry, stack<Pos>& paths)
{
	assert(a);
	//Pos cur = entry;
	paths.push(entry);
	while (!paths.empty())
	{
		Pos cur = paths.top();
		a[cur._row*n + cur._col] = 2;
		if (cur._row == n - 1)
		{
			return true;
		}
		Pos next = cur;
		//上
		next._row--;
		if (CheckIsAccess(a, n, next))
		{
			paths.push(next);
			continue;
		}
		//下
		next = cur;
		next._row++;
		if (CheckIsAccess(a, n, next))
		{
			paths.push(next);
			continue;
		}
		//左
		next = cur;
		next._col--;
		if (CheckIsAccess(a, n, next))
		{
			paths.push(next);
			continue;
		}
		//右
		next = cur;
		next._col++;
		if (CheckIsAccess(a, n, next))
		{
			paths.push(next);
			continue;
		}
		a[cur._row*n + cur._col] = 3;
		paths.pop();
	}
	return false;
}

测试用例:

void Test1()
{
	int a[N][N] = { 0 };
	GetMaze((int*)a, N);
	cout << "迷宫:" << endl;
	PrintMaze((int*)a, N);
	stack<Pos> paths;
	Pos entry = { 2,0 };//入口坐标
	cout << "是否有通路?" << SearchMazeSize((int*)a, N, entry, paths) << endl;
	cout << endl;
	PrintMaze((int*)a, N);
}
运行结果:




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值