본문 바로가기

Algorithms/Baekjoon OJ

[Baekjoon]5427.불

5427.불

http://www.acmicpc.net/problem/5427

 

5427번: 불

문제 상근이는 빈 공간과 벽으로 이루어진 건물에 갇혀있다. 건물의 일부에는 불이 났고, 상근이는 출구를 향해 뛰고 있다. 매 초마다, 불은 동서남북 방향으로 인접한 빈 공간으로 퍼져나간다. 벽에는 불이 붙지 않는다. 상근이는 동서남북 인접한 칸으로 이동할 수 있으며, 1초가 걸린다. 상근이는 벽을 통과할 수 없고, 불이 옮겨진 칸 또는 이제 불이 붙으려는 칸으로 이동할 수 없다. 상근이가 있는 칸에 불이 옮겨옴과 동시에 다른 칸으로 이동할 수 있다. 빌딩

www.acmicpc.net


3055.탈출과 거의 같은 문제였다. 다른 점은 이 문제에서는 도착지점이 맵에 주어져있지 않고 맵 밖으로 빠져나가야 탐색이 끝난다는 점이다. 

 

불이 번지는 것과 상근이가 이동하는것은 동시에 일어나기 때문에 불이 번질 예정인 곳으로는 상근이가 이동할 수 없다. 따라서 다음과 같이 접근했다.

  1. 불이 먼저 번진다.
  2. 불이 다 번지면 상근이가 이동한다.
  3. 상근이가 맵 밖으로 나가면 종료한다.

불이 번지는 것과 상근이가 이동하는것을 한 번씩 진행하면서 상근이가 맵 밖으로 나가는지 확인한다. 보통 bfs를 할 때 큐에 아무것도 없을 때까지 탐색을 진행하지만 이번에는 한 번씩 번갈아가면서 탐색을 해야하므로 큐를 두개 생성하여 각각의 큐의 사이즈 만큼만 탐색을 반복하도록 한다. (fire : 불이 번질때 사용할 큐, start: 상근이가 이동할때 사용할 큐)

 

맵에서 벽이 주어지지만 어차피 벽이 있는 곳으로는 불이 번지지 못하고 상근이도 이동할 수 없기 때문에 굳이 건드리지 않아도 된다. 

 

상근이의 이동을 위해 탐색을 진행할 때 start큐가 비어있지 않으면 이동이 이루어진것이므로 step++ 을 수행한다. 

private static void spreadFire() {

		while (!fire.isEmpty() || !start.isEmpty()) {
			
			int fsize = fire.size();
			for (int i = 0; i < fsize; i++) { // 불 먼저 bfs. 현재 칸의 상하좌우만 탐색. 큐에 다음 칸이 들어있지만 상근이 이동후에 다시 bfs 수행. 
				Point p = fire.poll();
				int curX = p.x;
				int curY = p.y;

				for (int j = 0; j < 4; j++) {
					int nextX = curX + dx[j];
					int nextY = curY + dy[j];

					if (nextX >= 0 && nextY >= 0 && nextX < W && nextY < H) {
						if (map[nextY][nextX] == '.' || map[nextY][nextX] == '@') {
							map[nextY][nextX] = '*';
							fire.add(new Point(nextX, nextY));
						}
					}
				}
			}

			int ssize = start.size();
			if (ssize > 0) {
				step++;

				for (int i = 0; i < ssize; i++) { // 상근이 이동 bfs. 
					Point p = start.poll();
					int curX = p.x;
					int curY = p.y;

					for (int j = 0; j < 4; j++) {
						int nextX = curX + dx[j];
						int nextY = curY + dy[j];

						if (nextX < 0 || nextY < 0 || nextX >= W || nextY >= H) {
							flag = true;
							return;
						}
						if (map[nextY][nextX] == '.') {
							map[nextY][nextX] = '@';
							start.add(new Point(nextX, nextY));
						}

					}
				}
			} else {
				return;
			}
		}
	}

<전체코드>

'Algorithms > Baekjoon OJ' 카테고리의 다른 글

[Baekjoon]14442.벽 부수고 이동하기2  (0) 2019.07.09
[Baekjoon]2206.벽 부수고 이동하기  (0) 2019.07.09
[Baekjoon]2146.다리만들기  (0) 2019.06.27
[Baekjoon]2589.보물섬  (0) 2019.06.26
[Baekjoon]2573.빙산  (0) 2019.06.25