문제링크 : https://www.acmicpc.net/problem/1600
1600번: 말이 되고픈 원숭이
첫째 줄에 정수 K가 주어진다. 둘째 줄에 격자판의 가로길이 W, 세로길이 H가 주어진다. 그 다음 H줄에 걸쳐 W개의 숫자가 주어지는데, 0은 아무것도 없는 평지, 1은 장애물을 뜻한다. 장애물이 있
www.acmicpc.net
접근 과정 :
- BFS 방식으로 접근해야겠다고 생각
- BFS를 진행하면서, 방문체크를 어떻게 해야할 지 고민
- int[][] visit로 방문을 체크하되. 그 값을 방문 당시의 남아있는 점프횟수로 하였다.
- 즉, visit[i][j]의 값의 현재 k의 값보다 크다면, 이미 이전에 방문했던 적이 있다고 판단.
소스 코드 및 결과 :
package BOJ;
/*
말이 되고픈 원숭이
*/
import java.io.*;
import java.util.*;
public class BOJ1600 {
static int[][] move = { { 0, -1 }, { 0, 1 }, { -1, 0 }, { 1, 0 } };
static int[][] jump = { { -1, -2 }, { -2, -1 }, { -2, 1 }, { -1, 2 }, { 1, 2 }, { 2, 1 }, { 2, -1 }, { 1, -2 } };
public static void main(String[] args) throws IOException {
int a = 1<<31;
System.out.println(a);
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int K = Integer.parseInt(br.readLine());
StringTokenizer st = new StringTokenizer(br.readLine());
int W = Integer.parseInt(st.nextToken());
int H = Integer.parseInt(st.nextToken());
int[][] map = new int[H][W];
int[][] visit = new int[H][W];
for (int i = 0; i < H; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < W; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
visit[i][j] = -1;
}
}
Queue<int[]> queue = new LinkedList<>();
queue.add(new int[] { 0, 0, K });
int count = 0;
while (!queue.isEmpty()) {
int size = queue.size();
while (size-- > 0) {
int[] monkey = queue.poll();
if (monkey[0] == H - 1 && monkey[1] == W - 1) {
System.out.println(count);
return;
}
if (visit[monkey[0]][monkey[1]] > monkey[2]) {
continue;
}
visit[monkey[0]][monkey[1]] = monkey[2];
for (int i = 0; i < 4; i++) {
int nr = monkey[0] + move[i][0];
int nc = monkey[1] + move[i][1];
if (nr < 0 || nr >= H || nc < 0 || nc >= W || map[nr][nc] == 1 || visit[nr][nc] > monkey[2]) {
continue;
}
queue.add(new int[] { nr, nc, monkey[2] });
}
if (monkey[2] > 0) {
for (int i = 0; i < 8; i++) {
int nr = monkey[0] + jump[i][0];
int nc = monkey[1] + jump[i][1];
if (nr < 0 || nr >= H || nc < 0 || nc >= W || map[nr][nc] == 1
|| visit[nr][nc] > monkey[2] - 1) {
continue;
}
queue.add(new int[] { nr, nc, monkey[2] - 1 });
}
}
}
count++;
}
System.out.println(-1);
}
}
P.S
전반적인 풀이 방법은 전형적인 BFS라고 생각한다.
다만, 방문 체크를 어떻게 하는지에 따라 효율성이 달라질 것이다....
(나도 고민해봐야겠다ㅏㅏㅏㅏ)
'Algorithm' 카테고리의 다른 글
[백준 Silver 3] 5397 키로거 - Java (0) | 2021.12.18 |
---|---|
[백준 Gold 4] 3055 탈출 - Java (0) | 2021.12.18 |
[백준 Platinum 5] 3197 백조의 호수 - Java (0) | 2021.12.17 |
[백준 Silver 3] 15270 친구 팰린드롬 - Java (0) | 2021.12.16 |
[백준 Gold 4] 21923 곡예 비행 - Java (0) | 2021.12.16 |