728x90
⬛ [BOJ] 14502. 연구소 - java
https://www.acmicpc.net/problem/14502
14502번: 연구소
인체에 치명적인 바이러스를 연구하던 연구소에서 바이러스가 유출되었다. 다행히 바이러스는 아직 퍼지지 않았고, 바이러스의 확산을 막기 위해서 연구소에 벽을 세우려고 한다. 연구소는 크
www.acmicpc.net
⬛ 문제 정리
- 0은 빈칸, 1은 벽, 2는 바이러스
- 바이러스(2)는 벽을 통과할 수 없고 빈칸(0)으로만 확산된다.
- 꼭 3개의 벽을 세워야 하고 벽을 세운 뒤, 바이러스가 퍼질 수 없는 곳을 안전 영역이라고 한다.
- 안전 영역 크기의 최댓값을 구하여라.
⬛ 풀이 방법
- map을 채울 때 빈칸(0)의 개수를 센다. -> zeroCnt
- dfs를 이용하여 3개의 벽을 세우는 완전 탐색 진행 -> setWall()
- 3개의 벽을 채운 뒤 bfs를 이용하여 바이러스(2)를 확산시킴 -> diffusion()
- boolean 배열 visited를 이용하여 바이러스(2)가 확산된 곳을 체크
- 빈칸(0) -> 바이러스(2)로 바뀔 때마다 cnt--

⬛ 소스 코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
public class BOJ_14502_연구소 {
static int[] dr = { -1, 1, 0, 0 };
static int[] dc = { 0, 0, -1, 1 };
static int zeroCnt, max, N, M;
static int[][] map;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] input = br.readLine().split(" ");
N = Integer.parseInt(input[0]);
M = Integer.parseInt(input[1]);
map = new int[N][M];
zeroCnt = 0;
max = 0;
for (int i = 0; i < N; i++) {
input = br.readLine().split(" ");
for (int j = 0; j < M; j++) {
map[i][j] = Integer.parseInt(input[j]);
if (map[i][j] == 0)
zeroCnt++;
}
}
zeroCnt -= 3;
setWall(0);
System.out.println(max);
}
public static void setWall(int cnt) { // 3개의 벽을 채우고 확산시켜본 후 0의 개수의 최댓값을 계산 //dfs
if (cnt == 3) {
int result = diffusion();
max = max < result ? result : max;
return;
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (map[i][j] == 0) {
map[i][j] = 1;
setWall(cnt + 1);
map[i][j] = 0;
}
}
}
}
public static int diffusion() { // 확산 //bfs
int cnt = zeroCnt;
boolean[][] visited = new boolean[N][M]; // map을 바꾸지 않고 0->2로 확산된 애들을 체크
Queue<int[]> queue = new LinkedList<>();
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (map[i][j] == 2) {
visited[i][j] = true;
queue.offer(new int[] { i, j });
}
}
}
while (!queue.isEmpty()) {
int[] cur = queue.poll();
int r = cur[0];
int c = cur[1];
for (int i = 0; i < 4; i++) {
int nr = r + dr[i];
int nc = c + dc[i];
if (nr >= 0 && nr < N && nc >= 0 && nc < M && map[nr][nc] == 0 && !visited[nr][nc]) { // 0이고 아직 2로 바뀌지 않은 것들만
visited[nr][nc] = true; // 2로 바뀐 애들은 visited처리
cnt = cnt - 1;
queue.offer(new int[] { nr, nc });
}
}
}
return cnt;
}
}
728x90
'공부의 기록 > Baekjoon' 카테고리의 다른 글
[BOJ] 2458. 키 순서 - java (SWEA_5643) (0) | 2022.04.08 |
---|---|
[Boj] 17070. 파이프 옮기기1 - java (0) | 2022.03.22 |
[Boj] 2464. 비밀번호 - java (0) | 2022.02.24 |