广度优先搜索,见注释
五个状态:上下左右停
题目提交
import java.util.ArrayDeque;
import java.util.Queue;
import java.util.Scanner;
public class 大胖子走迷宫 {
static int[][] map;//地图
static Node[][] path;//记录路径
static int[] xs = { 1, 0, -1, 0 };//坐标移动
static int[] ys = { 0, 1, 0, -1 };
static int n;
static int k;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
k = sc.nextInt();
map = new int[n][n];
path = new Node[n][n];
for (int i = 0; i < n; i++) {
String str = sc.next();
for (int j = 0; j < n; j++) {
map[i][j] = str.charAt(j);
}
}
sc.close();
System.out.println(bfs());
//输出路径
Node node = path[n - 3][n - 3];
while (node != path[2][2]) {
System.out.println(node);
node = path[node.x][node.y];
}
}
static int bfs() {
Queue<Node> q = new ArrayDeque<>();
q.add(new Node(2, 2, 0));
int[][] vis = new int[n][n];// 判重,但是可以在原地停留
vis[2][2] = 1;
while (!q.isEmpty()) {
Node node = q.poll();
int dis = node.dis;
int r;
if (dis < k)
r = 2;
else if (dis < (k << 1))
r = 1;
else
r = 0;
dis++;
if(r > 0) {// 表示原地停留,把时刻加一后放回队列,但是当r等于零时就没有等待的必要了
q.offer(new Node(node.x, node.y, dis));
}
for (int i = 0; i < 4; i++) {
int x = node.x + xs[i];
int y = node.y + ys[i];
if (x + r < n && x - r >= 0 && y + r < n && y - r >= 0) {
if (vis[x][y] == 0 && check(x, y, r)) {
q.offer(new Node(x, y, dis));
if (path[x][y] == null)
path[x][y] = node;
if (x == n - 3 && y == n - 3)
return dis;
vis[x][y] = 1;
}
}
}
}
return -1;
}
// 检查是否碰到障碍物
static boolean check(int x, int y, int r) {
for (int i = x - r; i <= x + r; i++)
for (int j = y - r; j <= y + r; j++)
if (map[i][j] == '*')
return false;
return true;
}
static class Node {//坐标及时刻
int x;
int y;
int dis;
public Node(int x, int y, int dis) {
this.x = x;
this.y = y;
this.dis = dis;
}
public Node() {
}
@Override
public String toString() {
return "Node [x=" + x + ", y=" + y + ", dis=" + dis + "]";
}
}
}