-
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 Position { int x; int y; Position(int x, int y) { this.x = x; this.y = y; } } public class Main { static String map[][]; static Queue<Position> water; static Queue<Position> animal; static int R; static int C; public static void main(String[] args) throws IOException{ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st= new StringTokenizer(br.readLine(), " " ); R = Integer.parseInt(st.nextToken()); C = Integer.parseInt(st.nextToken()); water = new LinkedList<>(); animal = new LinkedList<>(); map = new String[R][C]; for(int i= 0; i<R; i++) { String[] input = br.readLine().split(""); for(int j =0; j<C; j++) { String value = input[j]; map[i][j] = value; // 고슴도치 처음 위치 if(value.equals("S")) { animal.add(new Position(i,j)); } // 물 처음 위치 if(value.equals("*")) { water.add(new Position(i,j)); } } } String value = solve(); System.out.println(value); } public static String solve() { String result = ""; int time = 0; int dx [] = {-1,1,0,0}; int dy [] = {0,0,-1,1}; solve2 : while(true) { // 고슴도치가 더 이상 갈 곳이 없다는 뜻이므로 while 문 나옴. if(animal.isEmpty()) { result = "KAKTUS"; break solve2; } time++; // 1. 물 이동 int water_size = water.size(); // 매 시간마다 각 위치에 있는 물이 이동해야 하므로 water_size(각 위치 물의 수) 만큼 for 문 돌림. for(int i=0; i<water_size; i++) { Position p = water.poll(); int water_x = p.x; int water_y = p.y; for(int j=0; j<4; j++) { int nextX = water_x + dx[j]; int nextY = water_y + dy[j]; if(nextX>=0 && nextX<R && nextY>=0 && nextY<C) { // 물이 이동할 수 있는 곳 // 1. S 가 아니고 -> 물은 비어있는 곳으로만 이동 가능하므로 고슴도치가 있는 곳 안됨. // 2. D 비버의 굴이 아니고 // 3. X 돌이 아닌 // A는, 과거에 고슴도치가 이동한 곳. -> 지금은 비어있는 공간이므로 물이 이동 가능함. if(map[nextX][nextY].equals(".") || map[nextX][nextY].equals("A")) { // 물로 됨. map[nextX][nextY] = "*"; water.add(new Position(nextX, nextY)); } } } } // 2. 고슴도치 이동 int animal_size = animal.size(); for(int i= 0; i<animal_size; i++) { Position p = animal.poll(); int animal_x = p.x; int animal_y = p.y; for(int j=0; j<4; j++) { int nextX = animal_x + dx[j]; int nextY = animal_y + dy[j]; if(nextX>=0 && nextX<R && nextY>=0 && nextY<C) { // 고슴도치가 도착지에 도착했으므로 while 문 나옴 if(map[nextX][nextY].equals("D")) { result = Integer.toString(time); break solve2; } // 고슴도치가 이동할 수 있는 곳 // S가 아니고, 물(*)이 아니고, 돌(X)이 아닌 곳 // A(고슴도치가 과거에 있던 곳)도 아닌 장소 => 메모리 문제 if(map[nextX][nextY].equals(".")) { // 다음번에 고슴도치가 S나 A 인 곳에 이동하지 않도록 표시함 // 그래야 메모리 초과 안 남. // S : 고슴도치가 이번에 이동할 곳 map[nextX][nextY] = "S"; // A : 고슴도치가 이동 직전에 원래 있던 곳 map[animal_x][animal_y] = "A"; animal.add(new Position(nextX, nextY)); } } } } result = Integer.toString(time); } return result; } }
1. 핵심
일단 이 문제에서 핵심은
고슴도치는 물이 찰 예정인 칸으로 이동할 수 없다.
=> 하나의 while 문 내에서 매 분, 물과 고슴도치가 이동하는 것을 처리하는데
물 이동을 먼저 하면 된다.
2. 핵심
코드대로 진행하면,
예제 입력 2에서
다음과 같은 상황이 된다.
[1]
D . *
. . .
. . S
[2]
D * *
. . *
. S A
-> 일단 코드에서 보이듯이
고슴도치가 이동했을 때, S 표시(녹색)를 해준다.
이 전에 있던 위치는 헷갈리지 않도록 A (노랑색)표시함.
=> 다음번에 고슴도치는 S나 A 인 곳으로 이동하지 않게 해야 메모리 초과 안 나옴
[3]
D * *
. * *
S A *
-> 물은 첫번째 고슴도치가 있던 곳(노랑색)에도 이동 가능함.
[4]
D * *
* * *
S * *
-> 물은 두번째 고슴도치가 있던 곳(노랑색)에도 이동 가능함.
-> 어쨌든 결과적으로 고슴도치는 D까지 이동못함.
[BFS] 백준 - 탈출 (3055) / 자바
-문제 https://www.acmicpc.net/problem/3055 3055번: 탈출 사악한 암흑의 군주 이민혁은 드디어 마법 구슬을 손에 넣었고, 그 능력을 실험해보기 위해 근처의 티떱숲에 홍수를 일으키려고 한다. 이 숲에는
earthconquest.tistory.com
'백준 > 그래프 이론' 카테고리의 다른 글
1707 이분 그래프 (0) 2024.06.19 16928 뱀과 사다리 게임 (0) 2024.06.18 1068 트리 (0) 2024.06.12 14502 연구소 (2) 2024.06.10 17265 나의 인생에는 수학과 함께 (0) 2022.05.29