문제 원본 : https://www.acmicpc.net/problem/1600
1600번: 말이 되고픈 원숭이
첫째 줄에 정수 K가 주어진다. 둘째 줄에 격자판의 가로길이 W, 세로길이 H가 주어진다. 그 다음 H줄에 걸쳐 W개의 숫자가 주어지는데, 0은 아무것도 없는 평지, 1은 장애물을 뜻한다. 장애물이 있
www.acmicpc.net
import java.io.*;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int k = Integer.parseInt(br.readLine());
StringTokenizer st = new StringTokenizer(br.readLine());
int w = Integer.parseInt(st.nextToken());
int h = Integer.parseInt(st.nextToken());
String[][] map = new String[h][w];
for (int i = 0; i < h; ++i) {
map[i] = br.readLine().split(" ");
}
boolean[][][] v = new boolean[h][w][k + 1];
int[][][] dist = new int[h][w][k + 1];
int[][] dir = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}, {-2, 1}, {-1, 2}, {1, 2}, {2, 1}, {2, -1}, {1, -2}, {-1, -2}, {-2, -1}};
Queue<Pos> q = new LinkedList<>();
q.add(new Pos(0, 0, 0));
v[0][0][0] = true;
while (!q.isEmpty()) {
Pos p = q.poll();
for (int i = 0; i < 12; ++i) {
int ny = p.y + dir[i][0];
int nx = p.x + dir[i][1];
if (ny >= 0 && nx >= 0 && ny < h && nx < w && map[ny][nx].equals("0")) {
if (i < 4 && !v[ny][nx][p.knight]) {
q.add(new Pos(ny, nx, p.knight));
dist[ny][nx][p.knight] = dist[p.y][p.x][p.knight] + 1;
v[ny][nx][p.knight] = true;
} else if (i >= 4 && p.knight < k && !v[ny][nx][p.knight + 1]) {
q.add(new Pos(ny, nx, p.knight + 1));
dist[ny][nx][p.knight + 1] = dist[p.y][p.x][p.knight] + 1;
v[ny][nx][p.knight + 1] = true;
}
}
}
}
int ans = Integer.MAX_VALUE;
boolean isPossible = false;
for (int i = 0; i <= k; ++i) {
if (v[h - 1][w - 1][i]) {
isPossible = true;
ans = Math.min(ans, dist[h - 1][w - 1][i]);
}
}
bw.write(isPossible ? Integer.toString(ans) : Integer.toString(-1));
bw.close();
br.close();
}
public static class Pos {
public int y;
public int x;
public int knight;
public Pos(int y, int x, int knight) {
this.y = y;
this.x = x;
this.knight = knight;
}
}
}
- 2206. 벽 부수고 이동하기 문제와 유사한 문제이다.
- 다른 점은 벽 부수는 건 한 번까지만 되고 말처럼 이동하는 건 k번만큼 가능하다는 것뿐이다.
- 이제 이런 BFS 유형은 감을 잡은 것 같다.
'알고리즘 > BOJ' 카테고리의 다른 글
| [BOJ] 3190. 뱀 (0) | 2022.03.01 |
|---|---|
| [BOJ] 1074. Z (0) | 2022.02.28 |
| [BOJ] 2206. 벽 부수고 이동하기 (0) | 2022.02.27 |
| [BOJ] 1406. 에디터 (0) | 2022.02.26 |
| [BOJ] 5639. 이진 검색 트리 (0) | 2022.02.25 |