개발/알고리즘 풀이

백준] 3055 탈출

펭귀니 :) 2019. 11. 10. 05:17

백준 3055 탈출

BFS와 시뮬레이션이 합해진 문제였다!

idea는 고슴도치를 먼저 보내고 물을 채웠다는 거!

물을 먼저 채우면 고슴도치가 비버의 굴에 가지 못하는 경우가 발생한다.

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 Main_3055_탈출 {

	private static int R, C, gR, gC, ans;
	private static char[][] map;
	private static boolean[][] visited;

	public static void main(String[] args) throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

		StringTokenizer st = new StringTokenizer(in.readLine());

		R = Integer.parseInt(st.nextToken());
		C = Integer.parseInt(st.nextToken());

		map = new char[R][C];
		visited = new boolean[R][C];

		for (int i = 0; i < R; i++) {
			map[i] = in.readLine().toCharArray();
			for (int j = 0; j < C; j++) {
				if (map[i][j] == 'S') {
					gR = i;
					gC = j;
				}
			}
		}

		// ---------입력부

		// idea! 고슴도치 이동하고, 물채우고!

		bfs();

		if (ans == -1) {
			System.out.println("KAKTUS");
		} else {
			System.out.println(ans + 1);
		}

	}

	private static void bfs() {
		Queue<Info> qu = new LinkedList<>();
		Queue<Info> gQu = new LinkedList<>(); // 고슴도치
		gQu.add(new Info(gR, gC));
		visited[gR][gC] = true;
		// 물이 현재 어느 위치에 있는지 확인
		for (int i = 0; i < R; i++) {
			for (int j = 0; j < C; j++) {
				if (map[i][j] == '*')
					qu.add(new Info(i, j));
			}
		}

		Info info;
		while (!gQu.isEmpty()) {

			int size = gQu.size();
			for (int i = 0; i < size; i++) {
				info = gQu.poll();
				int r = info.r;
				int c = info.c;
				if (map[r][c] == '*') {
					continue;
				}
				map[r][c] = '.';

				// 고슴도쥐가 갈 수 있는 구역이 있는지 알아보기!
				// 상
				if (r - 1 >= 0 && (map[r - 1][c] == '.' || map[r - 1][c] == 'D') && !visited[r-1][c]) { //
					if (check(r - 1, c))
						return;
					map[r - 1][c] = 'S';
					gQu.add(new Info(r - 1, c));
				}
				// 하
				if (r + 1 < R && (map[r + 1][c] == '.' || map[r + 1][c] == 'D') && !visited[r+1][c]) {
					if (check(r + 1, c))
						return;
					map[r + 1][c] = 'S';
					gQu.add(new Info(r + 1, c));
				}
				// 좌
				if (c - 1 >= 0 && (map[r][c - 1] == '.' || map[r][c - 1] == 'D') && !visited[r][c-1]) {
					if (check(r, c - 1))
						return;
					map[r][c - 1] = 'S';
					gQu.add(new Info(r, c - 1));
				}

				// 우
				if (c + 1 < C && (map[r][c + 1] == '.' || map[r][c + 1] == 'D') && !visited[r][c+1]) {
					if (check(r, c + 1))
						return;
					map[r][c + 1] = 'S';
					gQu.add(new Info(r, c + 1));
				}
			}

			if (gQu.isEmpty()) {
				ans = -1;
				return;
			}

			ans++;

			// 물 채우기!
			size = qu.size();
			for (int i = 0; i < size; i++) {
				info = qu.poll();
				int r = info.r;
				int c = info.c;

				// 상
				if (r - 1 >= 0 && (map[r - 1][c] == '.' || map[r - 1][c] == 'S')) {
					map[r - 1][c] = '*'; // 물이 찰 수 있는 지역이면
					qu.add(new Info(r - 1, c));
				}
				// 하
				if (r + 1 < R && (map[r + 1][c] == '.' || map[r + 1][c] == 'S')) {
					map[r + 1][c] = '*'; // 물이 찰 수 있는 지역이면
					qu.add(new Info(r + 1, c));
				}
				// 좌
				if (c - 1 >= 0 && (map[r][c - 1] == '.' || map[r][c - 1] == 'S')) {
					map[r][c - 1] = '*'; // 물이 찰 수 있는 지역이면
					qu.add(new Info(r, c - 1));
				}

				// 우
				if (c + 1 < C && (map[r][c + 1] == '.' || map[r][c + 1] == 'S')) {
					map[r][c + 1] = '*'; // 물이 찰 수 있는 지역이면
					qu.add(new Info(r, c + 1));
				}
			}

		}

	}

	public static boolean check(int r, int c) {
		return map[r][c] == 'D' ? true : false;
	}

	private static class Info {
		int r, c;

		public Info(int r, int c) {
			this.r = r;
			this.c = c;
		}
	}

}

'개발 > 알고리즘 풀이' 카테고리의 다른 글

프로그래머스] 가장 큰 정사각형 찾기 (Java)  (0) 2020.02.10
SW Expert Academy] 1249 D4 보급로  (0) 2020.02.01
백준] 2636 치즈  (0) 2019.10.04
백준] 2630 색종이만들기  (0) 2019.10.04
정올] 2247 도서관  (0) 2019.09.30