题意:
走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;
}
}
}