-
[백준] 14502번 : 연구소 -자바(JAVA)알고리즘/백준 2022. 3. 30. 00:01
https://www.acmicpc.net/problem/14502
문제 해석
N x M 크기의 직사각형의 크기의 연구소가 존재합니다.
연구소는 빈칸, 벽으로 이루어져 있습니다.
일부 칸에 바이러스가 존재하고 바이러스는 상하좌우 인접한 칸으로 퍼져나갈 수 있습니다.
새로 세울 수 있는 벽의 개수는 3개이며 꼭 3개를 세워야 합니다.
이때 연구소의 지도가 주어졌을 때 벽을 새로 3개 세워서 안전 영역의 크기의 최댓값을 구하세요.
문제 풀이 전 설계
1. 벽 세우기
2. 벽을 고려해서 바이러스 전파(BFS)
3. 비어있는 칸 개수 세기 (최솟값 구해야 함)
N, M의 범위가 3 이상 8 이하입니다.
범위가 작기 때문에 임의의 벽을 3개 세워서 모두 탐색해보는 것이 우선적으로 떠오릅니다. (완전 탐색)
문제 풀이하면서
조합 + BFS를 진행해야 하는 문제였습니다.
항상 이런 문제가 나왔을 때 x, y의 좌표가 많이 헷갈리는 객체를 만들어서 해결해야겠습니다.
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Queue; import java.util.StringTokenizer; public class Main_14502_연구소 { static List<int[]> emptySpace = new ArrayList<int[]>(); static List<int[]> virusList = new ArrayList<int[]>(); static int WALL_COUNT = 3; static int[][] labBoard; static int[][] copyLabBoard; static int maxSafeArea = Integer.MIN_VALUE; static int N, M; static int[] dy = { -1, 1, 0, 0 }; static int[] dx = { 0, 0, -1, 1 }; public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine(), " "); N = Integer.parseInt(st.nextToken()); M = Integer.parseInt(st.nextToken()); // 세로크기 N, 가로크기M labBoard = new int[N][M]; for (int i = 0; i < N; i++) { st = new StringTokenizer(br.readLine(), " "); for (int j = 0; j < M; j++) { labBoard[i][j] = Integer.parseInt(st.nextToken()); if (labBoard[i][j] == 0) { emptySpace.add(new int[] { j, i }); } if (labBoard[i][j] == 2) { virusList.add(new int[] { j, i }); } } } //inputTest(); // 조합을 위한 배열 int[][] combinatedArray = new int[WALL_COUNT][2]; combination(0, 0, combinatedArray); System.out.println(maxSafeArea); } private static void inputTest() { for (int[] e : emptySpace) { System.out.println(e[1] + " " + e[0]); } System.out.println(emptySpace.size()); for(int [] e : virusList) { System.out.println(e[1] + " " + e[0]); } System.out.println(virusList.size()); } private static void combination(int cnt, int start, int[][] combinatedArray) { if (cnt == WALL_COUNT) { // BFS int tempSafeArea = getSafeArea(combinatedArray); maxSafeArea = maxSafeArea > tempSafeArea ? maxSafeArea : tempSafeArea; return; } for (int i = start; i < emptySpace.size(); i++) { //x combinatedArray[cnt][1] = emptySpace.get(i)[1]; //y combinatedArray[cnt][0] = emptySpace.get(i)[0]; combination(cnt + 1, i + 1, combinatedArray); } } private static int getSafeArea(int[][] combinatedArray) { int safeArea = 0; copyLabBoard = new int[N][M]; // 연구실 복사 for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { copyLabBoard[i][j] = labBoard[i][j]; } } // 벽 생성 for (int i = 0; i < 3; i++) { copyLabBoard[combinatedArray[i][1]][combinatedArray[i][0]] = 1; } // 바이러스 위치 탐색 for (int i = 0; i < virusList.size(); i++) { BFS(virusList.get(i)); } // 안전구역 count for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { if (copyLabBoard[i][j] != 0) { continue; } safeArea++; } } return safeArea; } private static void BFS(int[] virus) { Queue<int[]> q = new LinkedList<int[]>(); q.add(virus); while (!q.isEmpty()) { int x = q.peek()[0]; int y = q.peek()[1]; q.poll(); for (int k = 0; k < 4; k++) { int next_y = y + dy[k]; int next_x = x + dx[k]; if (next_y >= 0 && next_x >= 0 && next_y < N && next_x < M) { if (copyLabBoard[next_y][next_x] == 0) { copyLabBoard[next_y][next_x] = 2; q.add(new int[] { next_x, next_y }); } } } } } }
'알고리즘 > 백준' 카테고리의 다른 글
[백준] 1987번 : 알파벳 - 자바(JAVA) (0) 2022.04.02 [백준] 3109번 : 빵집 - 자바(JAVA) (0) 2022.03.31 [백준] 1992번 : 쿼드트리 - 자바(JAVA) (0) 2022.03.29 [백준] 11725번 : 트리의 부모 찾기 - 자바(JAVA) (0) 2022.03.27 [백준] 1074번 : Z - 자바(JAVA) (0) 2022.03.26