1. 문제
2. 접근방법
최단 거리 문제로 BFS를 써야하는데 1 하나를 부수고 간 상황과 안 부수고 간 상황 두가지를 구분해줘야 한다.
두 상황을 분리하기 위해 visit배열을 2개 써서 1을 하나 부수고 가는 visit처리 1을 안만나고 가는 visit처리 따로 해주었다.
3. 풀이
1. 상태 정보 저장할 class 생성 (row , col , cnt , one)
2. map[M][N]과 visit[2][M][N] 생성
3. bfs를 돌며 이동하되 1을 거친 것과 안 거친 상황을 나누어 visit처리하며 이동
4. M,N에 도착하면 최단 경로 출력
4. 자바 코드
package 백준;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
class room{
int row;
int col;
int cnt;
int one;
public room(int row, int col, int cnt, int one) {
super();
this.row = row;
this.col = col;
this.cnt = cnt;
this.one = one;
}
}
public class P2206벽부수고이동하기 {
static char map[][];
static int M,N;
static boolean visit[][][];
static int dr[] = {1,0,-1,0};
static int dc[] = {0,-1,0,1};
static int min = 123456789;
static void bfs(room r) {
Queue<room> que = new LinkedList<room>();
que.offer(r);
while(!que.isEmpty()) {
room now = que.poll();
if(now.row == M-1 && now.col == N-1) {
min = Math.min(min, now.cnt);
return;
}
for(int i = 0 ; i < 4 ; i++) {
int row = now.row+dr[i];
int col = now.col+dc[i];
if(row<0 || col<0 || row>=M || col>=N)
continue;
if(now.one == 0) {
if(visit[row][col][0])
continue;
if(map[row][col] == '1' ) {
que.offer(new room(row, col, now.cnt+1, now.one+1));
continue;
}
visit[row][col][0] = true;
que.offer(new room(row, col, now.cnt+1, now.one));
}
if(now.one == 1) {
if(visit[row][col][1] || visit[row][col][0])
continue;
if(map[row][col] == '1')
continue;
visit[row][col][1] = true;
que.offer(new room(row, col, now.cnt+1, now.one));
}
}
}
}
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 char[M][N];
visit = new boolean[M][N][2];
for(int i = 0 ; i < M ; i++ ) {
String str = br.readLine();
for(int j = 0 ; j < N ; j++) {
map[i][j] = str.charAt(j);
}
}
visit[0][0][0] = true;
bfs(new room(0, 0, 1, 0));
if(min == 123456789)
min = -1;
System.out.println(min);
}
}
5. 마치며
최단 거리를 구하는 문제이지만 1을 한번은 거칠 수 있다는 것을 어떻게 처리할지 조금 고민한 문제
visit을 2개로 처리 한다는 것만 떠올리면 쉽게 해결 할 수 있다.
'알고리즘 문제풀이 > 백준' 카테고리의 다른 글
[백준] 18513 샘터 (0) | 2020.08.31 |
---|---|
[백준] 17471 게리멘더링 (0) | 2020.08.28 |
[백준] 18808 스티커 붙이기 (0) | 2020.08.23 |
[백준] 2573 빙산 (0) | 2020.08.23 |
[백준] 1941 소문난 칠공주 (0) | 2020.08.21 |