【maze】定长走迷宫(BFS)

题目链接

题意:
走n*n迷宫,同一方向最多走m格

思路:
BFS,判断走四个方向,如果到达终点输出,到达边界、同方向超出m次跳过,到达走过的格子,比较该格同方向剩余可走连续长度,更好则更新否则跳过。

代码:copy他人提交通过代码,非原创,侵删,感谢!

#include<bits/stdc++.h>
using namespace std;
int t;
int n, m;
struct node {
	int x;
	int y;
	int dir;//来自方向
	int num;//该方向已走连续长度
	int len;//总共走的长度
};
char mp[101][101];//地图
int dis[101][101][4];//所有格子在不同方向上剩余可走距离,初始为-1
int ddir[][2] = {1, 0, -1, 0, 0, 1, 0, -1};//方向数组
int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin >> t;
	while (t--) {
		int flag = 1;//判断是否有解
		cin >> n >> m;
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= n; j++) {
				cin >> mp[i][j];
			}
		}
		queue<node>que;
		que.push({1, 1, -1, 0, 0});//初始起点格子,-1代表来自方向为-1
		memset(dis, -1, sizeof(dis));//所有格子在不同方向上剩余可走距离,初始为-1
		while (!que.empty()) {
			node temp = que.front();
			int x = temp.x, y = temp.y, dir = temp.dir, num = temp.num, len = temp.len;
			que.pop();
			if (x == n && y == n) {//到达终点输出当前len(BFS一定是最短的)
				cout << len << endl;
				flag = 0;//置flag为0
				break;
			}
			for (int i = 0; i < 4; i++) {//遍历四个方向走
				int dx = x + ddir[i][0], dy = y + ddir[i][1];//下一个要走的点
				if (dx < 1 || dx > n || dy < 1 || dy > n) {//超出边界,跳过
					continue;
				}
				if (mp[dx][dy] == '*') {//下一个要走的点不可走,跳过
					continue;
				}
				if (dir == i) {//下一个要走的点与来自方向相同(即同方向连续走)
					if (dis[dx][dy][i] >= m - num) {
					//如果下一个点在这个方向上剩余可走距离比当前剩余可走距离要更大
					//即前面出现过该方向更好的走法,跳过
						continue;
					}
					if (m - num - 1 >= 0) {//如果当前剩余可走距离更大,且可以走
						dis[dx][dy][i] = m - num - 1;//更新下一节点剩余可走距离
						que.push({dx, dy, i, num + 1, len + 1});//放入队列
					}
				} else {
					if(dis[dx][dy][i]>=m-1){//如果之前走过或者有更好的方法(应该没有吧都第一次走这个方向了),跳过(应该是判断之前走没走过吧)
						continue;
					}
					dis[dx][dy][i] = m - 1;
					que.push({dx, dy, i, 1, len + 1});
				}
			}
		}
		if (flag) {
			cout << -1 << endl;
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值