题意理解
这道题目难度不是很大,但是有很多细节。
- 关于越界的问题,注意由于机器人是一个球,因此不能贴着边缘走。
- 即使前方第一个方块由于已经访问过了而导致不能访问,前方第二个方块可能还没有访问过,此时如果没有障碍,是可以访问的。
- 与上一条形成对比的是,如果前方第一个方块由于路上有障碍而无法访问,那么前方第二个方块肯定也会被障碍挡住路。
- 往前走的代码按道理应该封装一下,但是我实在搞不动了。。。
代码
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class Main {
public static class FastScanner {
BufferedReader br;
StringTokenizer st;
public FastScanner() {
br = new BufferedReader(new InputStreamReader(System.in));
}
public FastScanner(String s) {
try {
br = new BufferedReader(new FileReader(new File(s)));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
String nextToken() {
while (st == null || !st.hasMoreElements()) {
try {
st = new StringTokenizer(br.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt() {
return Integer.valueOf(nextToken());
}
}
public static void main(String[] args) {
FastScanner fs = new FastScanner();
int N = fs.nextInt();
int M = fs.nextInt();
boolean[][][] visited = new boolean[55][55][4];
boolean[][] canPass = new boolean[55][55];
for (int i = 0; i < 55; i++) {
for (int j = 0; j < 55; j++) {
for (int k = 0; k < 4; k++) {
visited[i][j][k] = false;
}
canPass[i][j] = true;
}
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
int x = fs.nextInt();
if (x == 1) {
canPass[i][j] = false;
canPass[i + 1][j] = false;
canPass[i][j + 1] = false;
canPass[i + 1][j + 1] = false;
}
}
}
int startX = fs.nextInt();
int startY = fs.nextInt();
int endX = fs.nextInt();
int endY = fs.nextInt();
char direction = fs.nextToken().charAt(0);
String dirs = "ESWN";
int[] dx = { 0, 1, 0, -1 };
int[] dy = { 1, 0, -1, 0 };
Queue<Point> points = new LinkedList<>();
int dir = -1;
for (int i = 0; i < 4; i++) {
if (dirs.charAt(i) == direction) {
dir = i;
break;
}
}
Point start = new Point(startX, startY, dir, 0, "");
points.add(start);
while (!points.isEmpty()) {
Point temp = points.poll();
int tempStep = temp.step;
int tempX = temp.x;
int tempY = temp.y;
int tempDir = temp.dir;
String tempPath = temp.path;
if (tempX == endX && tempY == endY) {
System.out.println(temp.step);
return;
}
// 向前1步
int forward1X = tempX + dx[tempDir];
int forward1Y = tempY + dy[tempDir];
if (0 < forward1X && forward1X < N && 0 < forward1Y && forward1Y < M) {
if (canPass[forward1X][forward1Y]) {
if (!visited[forward1X][forward1Y][tempDir]) {
visited[forward1X][forward1Y][tempDir] = true;
points.add(new Point(forward1X, forward1Y, tempDir, tempStep + 1, tempPath + "1 "));
}
// 向前2步
int forward2X = tempX + dx[tempDir] * 2;
int forward2Y = tempY + dy[tempDir] * 2;
if (0 < forward2X && forward2X < N && 0 < forward2Y && forward2Y < M) {
if (canPass[forward2X][forward2Y]) {
if (!visited[forward2X][forward2Y][tempDir]) {
visited[forward2X][forward2Y][tempDir] = true;
points.add(new Point(forward2X, forward2Y, tempDir, tempStep + 1, tempPath + "2 "));
}
// 向前3步
int forward3X = tempX + dx[tempDir] * 3;
int forward3Y = tempY + dy[tempDir] * 3;
if (0 < forward3X && forward3X < N && 0 < forward3Y && forward3Y < M) {
if (canPass[forward3X][forward3Y] && !visited[forward3X][forward3Y][tempDir]) {
visited[forward3X][forward3Y][tempDir] = true;
points.add(new Point(forward3X, forward3Y, tempDir, tempStep + 1, tempPath + "3 "));
}
}
}
}
}
}
int leftDir = (tempDir + 1) % 4;
if (!visited[tempX][tempY][leftDir]) {
visited[tempX][tempY][leftDir] = true;
points.add(new Point(tempX, tempY, leftDir, tempStep + 1, tempPath + "L "));
}
int rightDir = (tempDir + 3) % 4;
if (!visited[tempX][tempY][rightDir]) {
visited[tempX][tempY][rightDir] = true;
points.add(new Point(tempX, tempY, rightDir, tempStep + 1, tempPath + "R "));
}
}
System.out.println("-1");
}
}
class Point {
int x;
int y;
int dir;
int step;
String path;
public Point(int x, int y, int dir, int step, String path) {
this.x = x;
this.y = y;
this.dir = dir;
this.step = step;
this.path = path;
}
}