java版
BFS
每一个位置下一步都有五种选择,上、下、左、右或乘飞行器,我们只需遍历每一种可行的路径,并记录从起点到该点的路径长度。取所有能到达终点的路径长度的最小值。


import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        int n = cin.nextInt();
        int m = cin.nextInt();
        String line = cin.nextLine();
        char[][] maze = new char[n][m];
        int sX = 0, sY = 0;
        for (int i = 0; i < n; i++) {
            line = cin.nextLine();
            for (int j = 0; j < line.length(); j++) {
                char ch = line.charAt(j);
                maze[i][j] = ch;
                if (ch == 'S') {
                    sX = i;
                    sY = j;
                }
            }
        }
        Deque<int[]> queue = new LinkedList<>();
        boolean[][] visied = new boolean[n][m];
        // 这四个值分别是该点的横坐标、纵坐标、飞行次数、路径长度
        queue.offer(new int[]{sX, sY, 0, 0});
        visied[sX][sY] = true;
        int minPath = Integer.MAX_VALUE - 1;
        int[][] detection = new int[][]{{-1, 0}, {1, 0}, {0, -1}, {0, 1}, {n - 1, m - 1}};
        while (!queue.isEmpty()) {
            int[] node = queue.poll();
            int x = node[0];
            int y = node[1];
            int flyNum = node[2];
            int path = node[3];
            for (int i = 0; i < 5; i++) {
                int newX, newY, newFlyNum, newPath;
                if (i == 4) {
                    // i = 4 为乘飞行器,飞行次数不能超过5次
                    if (flyNum > 5) {
                        break;
                    }
                    newX = detection[i][0] - x;
                    newY = detection[i][1] - y;
                    newFlyNum = flyNum + 1;
                } else {
                    newX = x + detection[i][0];
                    newY = y + detection[i][1];
                    newFlyNum = flyNum;
                }
                // 判断路径是否合法
                if (newX < 0 || newX >= n || newY < 0 || newY >= m || maze[newX][newY] == '#' || visied[newX][newY]) {
                    continue;
                }
                // 来到这里说明该路径是合法的
                newPath = path + 1;
                if (maze[newX][newY] == 'E') {
                    minPath = Math.min(minPath, newPath);
                    continue;
                }
                queue.offer(new int[]{newX, newY, newFlyNum, newPath});
                visied[newX][newY] = true;
            }
        }
        if (minPath == Integer.MAX_VALUE - 1) {
            System.out.println(-1);
        } else {
            System.out.println(minPath);
        }
    }
}