-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathBOJ_1726.java
More file actions
110 lines (89 loc) · 3.89 KB
/
BOJ_1726.java
File metadata and controls
110 lines (89 loc) · 3.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package week03.geun0;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.Queue;
import java.util.StringTokenizer;
/**
* <a href = "https://www.acmicpc.net/problem/1726">백준 1726번 - 로봇</a>
* @since 2025-07-13
* @author 장근영
* @apiNote 예상 시간 복잡도 {@code O(NM)}
*/
public class BOJ_1726 {
static int n, m;
static int[][] map;
static boolean[][][] visit;
static int[] dx = {0, 0, 1, -1}; //동서남북
static int[] dy = {1, -1, 0, 0}; //동서남북
static int[] turnLeft = {3, 2, 0, 1};
static int[] turnRight = {2, 3, 1, 0};
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
m = Integer.parseInt(st.nextToken()); //세로
n = Integer.parseInt(st.nextToken()); //가로
map = new int[m][n];
visit = new boolean[m][n][4]; //방향(동서남북)을 포함한 3차원 방문 배열 필요
for (int i = 0; i < m; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < n; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
}
}
//로봇의 출발 지점과 바라보는 방향
st = new StringTokenizer(br.readLine());
int sx = Integer.parseInt(st.nextToken()) - 1;
int sy = Integer.parseInt(st.nextToken()) - 1;
int sdir = Integer.parseInt(st.nextToken()) - 1;
//로봇의 도착 지점과 바라보는 방향
st = new StringTokenizer(br.readLine());
int ex = Integer.parseInt(st.nextToken()) - 1;
int ey = Integer.parseInt(st.nextToken()) - 1;
int edir = Integer.parseInt(st.nextToken()) - 1;
bfs(sx, sy, sdir, ex, ey, edir);
}
private static void bfs(int sx, int sy, int sdir, int ex, int ey, int edir) {
Queue<int[]> qu = new ArrayDeque<>();
qu.offer(new int[]{sx, sy, sdir, 0}); //{x 좌표, y 좌표, 바라보는 방향, 명령 횟수}
visit[sx][sy][sdir] = true; //시작 위치 방문 처리
while (!qu.isEmpty()) {
int[] cur = qu.poll();
int x = cur[0], y = cur[1]; //좌표
int dir = cur[2]; //바라보는 방향
int count = cur[3]; //명령 횟수
//도착 지점 + 바라보는 방향까지 같아야 함 주의
if (x == ex && y == ey && dir == edir) {
System.out.println(count);
return;
}
//명령 1 - 현재 향하고 있는 방향으로 1~3칸 만큼 움직인다.
for (int i = 1; i <= 3; i++) {
int nx = x + (i * dx[dir]);
int ny = y + (i * dy[dir]);
//범위를 벗어나는 경우
if (nx < 0 || ny < 0 || nx >= m || ny >= n) continue;
//2칸 이상 움직일 때 중간에 갈 수 없는 지점이 있으면 break
//continue를 해버리면 갈 수 없는 지점을 점프해버리는 문제가 발생한다.
if (map[nx][ny] == 1) break;
if (!visit[nx][ny][dir]) {
visit[nx][ny][dir] = true;
qu.offer(new int[]{nx, ny, dir, count + 1});
}
}
//명령 2 - 왼쪽 90도 회전
int left = turnLeft[dir];
if (!visit[x][y][left]) {
visit[x][y][left] = true;
qu.offer(new int[]{x, y, left, count + 1});
}
//명령 2 - 오른쪽 90도 회전
int right = turnRight[dir];
if (!visit[x][y][right]) {
visit[x][y][right] = true;
qu.offer(new int[]{x, y, right, count + 1});
}
}
}
}