Algorithm/백준 자바
백준 14502 자바
눈오는1월
2024. 1. 27. 00:16
728x90
<문제>
https://www.acmicpc.net/problem/14502
14502번: 연구소
인체에 치명적인 바이러스를 연구하던 연구소에서 바이러스가 유출되었다. 다행히 바이러스는 아직 퍼지지 않았고, 바이러스의 확산을 막기 위해서 연구소에 벽을 세우려고 한다. 연구소는 크
www.acmicpc.net
<풀이>
위 문제 같은 경우 벽을 3개를 세울 수 있다. 또한 N,M의 범위가 매우 작다. 그래서 나는 dfs 와 bfs를 하나씩 이용해서 풀어야 된다는 생각을 했다.
맨처음에 map 을 입력받는다. 이 맵과 벽이 생길때마다 해당 맵을 clone()을 통해 복사해서 사용을 해야한다.먼저 벽을 세우는 곳을 dfs로 푼다. 그리고 벽이 3개가 됐을 경우에는 bfs로 넘어가서 바이러스가 갈 수 있는 모든 곳을 2로 변경한다. 이후 안전영역의 크기를 2차원 반복문을 이용해 가장 큰 안전영역을 구해서 출력하면 된다.
해당 문제를 풀때 다른 bfs문제처럼 boolean 값을 가질 수 있는 이차원 배열 visited를 만들었지만, 바이러스가 퍼진 곳에 값을 2로 바꾸면 되기 때문에 visited 배열이 필요 없게 되었다.
난이도가 올라갈수록 하나의 문제에 하나의 알고리즘이 쓰이지 않는다는 것을 기억해야한다. 위 문제는 그래도 비슷한 그래프 탐색 알고리즘이 쓰였지만, 다른 알고리즘 2개가 사용될 수 있다는 것을 생각을 해야할거같다.
<코드>
import java.util.*;
import java.io.*;
public class Main {
public static int n;
public static int m;
public static int[][] map;
public static int[] dx = {-1,1,0,0};
public static int[] dy = {0,0,-1,1};
public static int safeZoneSize = 0;
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());
map = new int[n][m];
for(int i = 0; i < n; i++) { // 입력
StringTokenizer st2 = new StringTokenizer(br.readLine());
for(int j = 0; j < m; j++) {
map[i][j] = Integer.parseInt(st2.nextToken());
}
}
dfs(0);
System.out.println(safeZoneSize);
}
public static void dfs(int cnt) {
if(cnt == 3) {
bfs();
return;
}
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
if(map[i][j] == 0){
map[i][j] = 1;
dfs(cnt + 1);
map[i][j] = 0;
}
}
}
}
public static void bfs() {
Queue<int[]> queue = new LinkedList<>();
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
if(map[i][j] == 2) {
queue.add(new int[] {i,j});
}
}
}
int[][] copyMap = new int[n][m];
for(int i = 0; i < n; i++) {
copyMap[i] = map[i].clone();
}
while(!queue.isEmpty()) {
int now[] = queue.poll();
int nowX = now[0];
int nowY = now[1];
for(int i = 0; i < 4; i++) {
int nextX = nowX + dx[i];
int nextY = nowY + dy[i];
if(nextX < 0 || nextY < 0 || nextX >=n || nextY >= m) continue;
if(copyMap[nextX][nextY] == 0) {
queue.add(new int[] {nextX, nextY});
copyMap[nextX][nextY] = 2;
}
}
}
safeZone(copyMap);
}
public static void safeZone(int[][] copyMap) {
int size = 0;
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
if(copyMap[i][j] == 0) size++;
}
}
safeZoneSize = Math.max(safeZoneSize, size);
}
}
728x90