📝문제 설명
- 0은 빈칸, 1은 벽, 2는 바이러스
- 바이러스는 상하좌우로 움직이며 벽으로 가로막혀 있으면 퍼질 수 없다.
- 벽을 3개를 모두 세운 뒤 바이러스를 퍼트린 후, 0 빈칸의 개수가 최대인 값을 구하면 된다.
📢입출력 예시
✏️문제 풀이
package Baekjoon.Graph;
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 Baek14502 {
static int[][] map;
static int[][] copymap;
static int[] dx = {-1, 0, 1, 0};
static int[] dy = {0, 1, 0, -1};
static int countMax = Integer.MIN_VALUE;
static int N, M, count;
public static void main(String[] arg) throws IOException{
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(bf.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
map = new int[N][M];
for(int i=0; i<N; i++){
st = new StringTokenizer(bf.readLine());
for(int j=0; j<M; j++){
map[i][j] = Integer.parseInt(st.nextToken());
}
}
DFS(0);
System.out.println(countMax);
}
private static void DFS(int depth){
if(depth == 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(depth+1);
map[i][j] = 0;
}
}
}
}
private static void BFS(){
Queue<Virus> queue = new LinkedList<>();
copymap = new int[N][M];
for(int i=0; i<N; i++){
copymap[i] = map[i].clone();
}
for(int i=0; i<N; i++){
for(int j=0; j<M; j++){
if(copymap[i][j] == 2){
queue.offer(new Virus(i,j));
}
}
}
while(!queue.isEmpty()){
Virus virus = queue.poll();
int currentX = virus.x;
int currentY = virus.y;
for(int i=0; i<4; i++){
int newX = currentX + dx[i];
int newY = currentY + dy[i];
if(newX >= 0 && newY >= 0 && newX < N && newY < M){
if(copymap[newX][newY] == 0){
copymap[newX][newY] = 2;
queue.offer(new Virus(newX, newY));
}
}
}
}
countSafeZone(copymap);
}
private static void countSafeZone(int[][] copy){
count = 0;
for(int i=0; i<N; i++){
for(int j=0; j<M; j++){
if(copy[i][j] == 0){
count++;
}
}
}
countMax = Math.max(countMax, count);
}
private static class Virus{
int x;
int y;
Virus(int x, int y){
this.x = x;
this.y = y;
}
}
}
- 이 문제는 DFS, BFS 두개의 알고리즘을 제대로 알고있는지 묻는 문제라고 생각한다.
- DFS를 사용하여 기둥을 세울 수 있는 모든 조건들을 파악하고, 3개가 세워진다면 BFS로 진입한다.
- BFS에서 바이러스를 퍼트린 후, 안전지대를 개수를 파악한다.
- BFS가 끝나면 DFS로 돌아와 MAP을 원상복구한다.
- BFS를 수행할 때 map을 copymap으로 복제를 하는데 그 이유는 map을 그대로 유지하면 기존 맵의 정보가 달라지기 때문이다.
💡새로 알게된 점
- DFS와 BFS 알고리즘을 언제 적절히 사용해야 되는지 깨달아버렸다
'📖Algorithm > DFS & BFS' 카테고리의 다른 글
JAVA [Algorithm] - 백준 2206 벽 부수고 이동하기 (0) | 2024.12.18 |
---|---|
JAVA [Algorithm] - 백준 7576 토마토 (1) | 2024.12.17 |
JAVA [Algorithm] - 백준 1697 숨바꼭질 (0) | 2024.12.16 |
JAVA [Algorithm] - 백준 2178 미로 탐색 (2) | 2024.12.14 |
JAVA [Algorithm] - 백준 2667 단지번호 붙이기 (0) | 2024.12.14 |