- 생각
1. 이전에 벽 부수고 이동하기 문제를 푼적이 있었다. 여기서 달라진 점은 벽이 1개냐 K개냐 라는 차이 하나만 있기때문에 벽을 체크해주는 부분을 1개가 아닌 K개로 바꾸면 잘 동작할 것 같았다.
- 코드
정답 코드 : bfs로 풀었다. 여기서 핵심은 중복제거를 check[N][M][K]로 벽을 지나오면서 왔는지 아닌지 중복체크를 해주는 방법을 사용해야지만 정확히 풀 수 있는 문제이다.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class Main {
static int N, M, minValue, K;
static int[][] array;
static boolean[][][] check;
static int[] x = { -1, 1, 0, 0 };
static int[] y = { 0, 0, -1, 1 };
public static void main(String[] args) throws Exception {
SetData();
bfs();
if(minValue == Integer.MAX_VALUE)
System.out.println(-1);
else
System.out.println(minValue);
}
private static void SetData() throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
K = Integer.parseInt(st.nextToken());
array = new int[N][M];
check = new boolean[N][M][K+1];
minValue = Integer.MAX_VALUE;
String s;
for (int i = 0; i < N; i++) {
s = br.readLine();
for (int j = 0; j < M; j++) {
array[i][j] = s.charAt(j) - '0';
}
}
}
private static void bfs() {
Queue<int[]> queue = new LinkedList<>();
queue.offer(new int[] { 0, 0, 1, 0 });
while (!queue.isEmpty()) {
int location[] = queue.poll();
int count = location[2];
int breakWall = location[3];
if (location[0] == N - 1 && location[1] == M - 1) {
minValue = Math.min(minValue, count); // 마지막 위치에 도달했을 때 지나온 칸 수를 return
}
for (int direction = 0; direction < 4; direction++) {
int r = location[0] + x[direction];
int c = location[1] + y[direction];
if (r < 0 || r >= N || c < 0 || c >= M)
continue;
if (array[r][c] == 1 && breakWall == K) // 지나온 벽이 있고 다음 칸도 벽이면 진행 X
continue;
if (breakWall == K) {
if (!check[r][c][breakWall] && array[r][c] == 0) {
check[r][c][breakWall] = true;
queue.offer(new int[] { r, c, count + 1, breakWall});
}
} else { // 벽을 안부순 상태
if (!check[r][c][breakWall] && array[r][c] == 1) {
check[r][c][breakWall] = true;
queue.offer(new int[] { r, c, count + 1, breakWall + 1 });
} else if (!check[r][c][breakWall] && array[r][c] == 0) {
check[r][c][breakWall] = true;
queue.offer(new int[] { r, c, count + 1, breakWall });
}
}
}
}
}
}
'algorithm' 카테고리의 다른 글
[JAVA] 백준 1057번 : 토너먼트 (0) | 2020.11.25 |
---|---|
[JAVA] 백준 13164번 : 행복 유치원 (0) | 2020.11.24 |
[JAVA] 백준 1092번 : 배 (0) | 2020.11.21 |
[JAVA] 백준 1676번 : 팩토리얼 0의 개수 (0) | 2020.11.20 |
[JAVA] 백준 2407번 : 조합 (0) | 2020.11.20 |