acmicpc
[BAEKJOON] 2206. 벽 부수고 이동하기
코드와이
2021. 3. 25. 17:33
그래프 탐색
너비 우선 탐색
문제링크
2206번: 벽 부수고 이동하기
N×M의 행렬로 표현되는 맵이 있다. 맵에서 0은 이동할 수 있는 곳을 나타내고, 1은 이동할 수 없는 벽이 있는 곳을 나타낸다. 당신은 (1, 1)에서 (N, M)의 위치까지 이동하려 하는데, 이때 최단 경로
www.acmicpc.net
※ visited 라는 3차원 boolean 배열 사용
package acmicpc.Gold4;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class 벽_부수고_이동하기 {
static int n, m, ans;
static char[][] arr;
static boolean visited[][][];
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
arr = new char[n][m];
visited = new boolean[n][m][2];
for(int i = 0 ; i < n ; i++) {
arr[i] = br.readLine().toCharArray();
}
ans = -1;
bfs();
System.out.println(ans == -1 ? -1 : ans);
}
static int[] dr = {-1, 0, 1, 0};
static int[] dc = {0, 1, 0, -1};
private static void bfs() {
// r, c, sum, chance
Queue<int[]> queue = new LinkedList<int[]>();
queue.add(new int[] {0,0,1,1});
while(!queue.isEmpty()) {
int[] q = queue.poll();
if(q[0] == n-1 && q[1] == m-1) {
ans = q[2];
return;
}
for(int d = 0 ; d < 4 ; d++) {
int nr = q[0] + dr[d];
int nc = q[1] + dc[d];
if(nr >= 0 && nc >= 0 && nr < n && nc < m ) {
if(arr[nr][nc] == '0') {
if(!visited[nr][nc][q[3]]) {
queue.add(new int[] {nr, nc, q[2] + 1, q[3]});
visited[nr][nc][q[3]] = true;
}
} else if(arr[nr][nc] == '1' && q[3] == 1) {
visited[nr][nc][q[3]] = true;
queue.add(new int[] {nr, nc, q[2] + 1, q[3] - 1});
}
}
}
}
}
}