문제
시간이 지날 수록 물이 차오르는 상황에서 고슴도치 집에서 출발한 고슴도치가 친구인 비버 집에 얼마만에 도착할 수 있는가를 구하는 문제. R행 C열로 이뤄진 지도에는 빈칸(.), 물(*), 돌(X), 비버집(D), 고슴도치집(S)이 주어져있다. 매 분마다 고슴도치는 현재 있는 칸과 인접한 네 칸 중 하나로 이동할 수 있고, 물도 매 분마다 비어있는 칸으로 확장한다. 물이 있는 칸과 인접해있는 비어있는 칸은 물이 차게 된다. 물과 고슴도치는 돌을 통과할 수 없다. 또, 고슴도치는 물로 차있는 구역으로 이동할 수 없고, 물도 비버의 소굴로 이동할 수 없다. 이러한 지도가 주어졌을 때, 고슴도치가 안전하게 비버의 굴로 이동하기 위해 필요한 최소 시간을 구하는 문제.
접근방법
맵의 입력을 숫자로 변환하여 받는다.
빈칸(-2), 물(-1), 돌(2) 고슴도치집(0), 비버집(-100)으로 설정하였다. → 처음 큐에 들어가면서 1씩 증가해야 하므로 고슴도치 집을 0으로 설정하였고, 이와 구분해주기 위해 다른 값들은 위와 같이 설정하였다.
입력을 받으면서 물을 큐에 넣고, 그 뒤에 고슴도치의 위치를 큐에 넣으면서 BFS를 수행한다.
소스코드
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Main{
static int[] dr = {1, -1, 0, 0};
static int[] dc = {0, 0, 1, -1};
static class Pos{
int r;
int c;
public Pos(int r, int c) {this.r = r; this.c = c;}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
int M = sc.nextInt();
Queue<Pos> queue = new LinkedList<>();
int map[][] = new int[N+2][M+2];
boolean check_doch[][] = new boolean[N+2][M+2];
boolean check_rain[][] = new boolean[N+2][M+2];
// 돌(테두리) 세우기
for(int i=0; i<N+2; i++)
for(int j=0; j<M+2; j++)
map[i][j] = 2; // 1-벽(돌)
Pos dochi = new Pos(0,0);
Pos bibber = new Pos(0,0);
for(int i=1; i<=N; i++){
String line = sc.next();
for(int j=1; j<=M; j++){
char input = line.charAt(j-1);
switch (input){
case '*': // 물
map[i][j] = -1;
queue.offer(new Pos(i, j));
check_rain[i][j] = true;
break;
case 'S': // 고슴도치 집
map[i][j] = 0;
dochi = new Pos(i, j);
break;
case '.': // 빈칸
map[i][j] = -2;
break;
case 'D': // 비버 집
map[i][j] = -100;
bibber = new Pos(i, j);
break;
case 'X': // 돌
map[i][j] = 2;
break;
}
}
}
queue.offer(dochi);
check_doch[dochi.r][dochi.c] = true;
First_Loop:
while(!queue.isEmpty()) {
Pos cur_pos = queue.poll();
for (int i = 0; i < 4; i++) {
Pos next_pos = new Pos(cur_pos.r + dr[i], cur_pos.c + dc[i]);
// 현재 칸이 빗물일 경우 -> 빗물 증가 (방문여부 확인할 필요x)
if (map[cur_pos.r][cur_pos.c] == -1) {
// 주변 칸이 빈칸(-2)일 경우 큐에 넣는다.
if (map[next_pos.r][next_pos.c] == -2) {
map[next_pos.r][next_pos.c] = -1;
check_rain[next_pos.r][next_pos.c] = true;
queue.offer(next_pos);
}
} // 현재 칸이 빈칸일 경우 -> 고슴도치 이동거리 증가
else {
// 주변 칸이 방문하지 않았으면서
if (!check_doch[next_pos.r][next_pos.c]) {
// 비버의 집(-100)일 경우 while문 탈출
if (map[next_pos.r][next_pos.c] == -100){
map[next_pos.r][next_pos.c] = map[cur_pos.r][cur_pos.c] + 1;
break First_Loop;
}// 빈칸(-2)일 경우 계속해서 이동
else if(map[next_pos.r][next_pos.c] == -2){
map[next_pos.r][next_pos.c] = map[cur_pos.r][cur_pos.c] + 1;
check_doch[next_pos.r][next_pos.c] = true;
queue.offer(next_pos);
}
}
}
}
}
if(map[bibber.r][bibber.c] == -100)
System.out.println("KAKTUS");
else
System.out.println(map[bibber.r][bibber.c]);
}
}
'알고리즘' 카테고리의 다른 글
백준15684 : 사다리 조작 (0) | 2018.11.21 |
---|---|
백준14889 : 스타트와 링크 (0) | 2018.11.16 |
[JAVA] 백준 11559 : 뿌요뿌요 (0) | 2018.09.20 |
[JAVA] 백준 14503 : 로봇 청소기 (0) | 2018.09.18 |
[JAVA] 백준 3190 : 뱀 (1) | 2018.09.18 |