import java.util.LinkedList; import java.util.Queue; import java.util.Scanner; public class Main { private static final int[] dX = new int[]{0, 0, 1, -1}; private static final int[] dY = new int[]{1, -1, 0, 0}; private static int row; private static int column; private static char[][] board; private static boolean[][][][] visited; private static Location start; private static Location end; private static Location startBox; private static int result = Integer.MAX_VALUE; private static Queue<Step> stepsQueue = new LinkedList<>(); public static void main(String[] args){ Scanner in = new Scanner(System.in); while(in.hasNext()){ row = in.nextInt(); column = in.nextInt(); board = new char[row][column]; for(int i=0; i<row; i++){ board[i] = in.next().toCharArray(); } visited = new boolean[row][column][row][column]; for(int i=0; i<row; i++){ for(int j=0; j<column; j++){ if(board[i][j] == 'S'){ start = new Location(i, j); } if(board[i][j] == 'E'){ end = new Location(i, j); } if(board[i][j] == '0'){ startBox = new Location(i, j); } } } solutionBFS(); } } /** * 模拟法: 适合BFS */ private static void solutionBFS(){ Step startStep = new Step(start.x, start.y, startBox.x, startBox.y, 0); stepsQueue.add(startStep); bfs(); if(result == Integer.MAX_VALUE){ System.out.println(-1); }else{ System.out.println(result); } } /** * BFS */ private static void bfs(){ while (!stepsQueue.isEmpty()){ Step curr = stepsQueue.poll(); if(curr.bx==end.x && curr.by==end.y){ result = curr.count; break; } for(int i=0; i<4; i++){ Step next; // 下一步 到达 箱子位置 if(curr.px+dX[i]==curr.bx && curr.py+dY[i]==curr.by){ // 人和箱子都移动 next = new Step(curr.px + dX[i], curr.py + dY[i], curr.bx + dX[i], curr.by + dY[i], curr.count + 1); }else{ // 仅人移动 next = new Step(curr.px + dX[i], curr.py + dY[i], curr.bx, curr.by, curr.count + 1); } if(canGo(next)){ visited[next.px][next.py][next.bx][next.by] = true; stepsQueue.add(next); } } } } /** * 下一步是否可行 * @param next * @return */ private static boolean canGo(Step next){ // 验证人位置 // 越界 if(next.px<0 || next.py<0 || next.px>=row || next.py>=column){ return false; } // 墙壁 if(board[next.px][next.py] == '#'){ return false; } // 验证箱子位置 // 越界 if(next.bx<0 || next.by<0 || next.bx>=row || next.by>=column){ return false; } // 墙壁 if(board[next.bx][next.by] == '#'){ return false; } // 已访问 if(visited[next.px][next.py][next.bx][next.by]){ return false; } return true; } /** * 位置(row, column) */ private static class Location { int x; int y; private Location(int x, int y){ this.x = x; this.y = y; } } /** * 移动: 步 */ private static class Step { // 人位置 int px; int py; // 箱子位置 int bx; int by; int count; private Step(int px, int py, int bx, int by, int count){ this.px = px; this.py = py; this.bx = bx; this.by = by; this.count = count; } } }