백준 - 연구소(14502) - Java - DFS+BFS

chaemin·2024년 2월 27일
0

백준

목록 보기
6/26

DFS + BFS

섞어서 푸는건 보통 DFS로 경우의 수를 구하고 BFS로 탐색하는 편이다.

1. 문제

https://www.acmicpc.net/problem/14502

비슷한 문제: https://www.acmicpc.net/problem/18428

2. 풀이

  1. DFS로 벽 세우는 경우의 수 구하기
  1. 다음 BFS로 탐색하는 두가지 경우가 있는데
    1. 2중 for문을 돌면서 map[i][j]가 2일경우 Queue에 담아 탐색을 시작하는경우
  1. map[i][j]가 2인 경우만 Queue에 담아서 진행하는 경우이다.

3. 코드

  1. 2중 for문으로 진행
import java.util.*;
import java.io.*;

public class Main {
	
	static int map[][];
	static int tmp[][];
	
	static int N;
	static int M;
	
	static int move_x[] = {1, -1, 0, 0};
	static int move_y[] = {0, 0, 1, -1};
	
	static ArrayList<Integer> answer = new ArrayList<>();

	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];
		tmp = new int[N][M];
		
		for(int n = 0; n < N; n++) {
            st = new StringTokenizer(br.readLine(), " ");
			for(int m = 0; m < M; m++)
				map[n][m] = Integer.parseInt(st.nextToken());
		}
		
		dfs(0);
		System.out.println(Collections.max(answer));

	}
	
	public static void dfs(int count) {
		
		if(count == 3) {
            
			for(int i = 0; i < N; i++) {
				for(int j = 0; j < M; j++)
					tmp[i][j] = map[i][j];
			}
			
			int result = bfs();
			answer.add(result);
			return;
		}
		
		for(int i = 0; i < N; i++) {
			for(int j = 0; j < M; j++) {
				if(map[i][j] == 0) {
					
					map[i][j] = 1;
					count += 1;
					dfs(count);
					map[i][j] = 0;
					count -= 1;
				}
				
			}
		}
		
	}
	
	public static int bfs() {
        
		Queue<Integer> QX = new LinkedList<>();
		Queue<Integer> QY = new LinkedList<>();
		
		//2. bfs를 돌면서 바이러스를 퍼트려준다.
		for(int i = 0; i < N; i++) {
			for(int j = 0; j < M; j++) {
				
				if(tmp[i][j] == 2) {
					QX.add(i);
					QY.add(j);
				}
				
				while(!QX.isEmpty()) {
					
					int X = QX.poll();
					int Y = QY.poll();
					
					for(int mx = 0; mx < move_x.length; mx++) {
						
						int go_x = X + move_x[mx];
						int go_y = Y + move_y[mx];
						
						if(go_x >= 0 && go_y >= 0 && go_x < N && go_y < M) {
                            
							if(tmp[go_x][go_y] == 0) {
								
								QX.add(go_x);
								QY.add(go_y);
								
								tmp[go_x][go_y] = 2;
							}
						}
					}
				}
			}
		}
		
		int result = 0;
		//3. 돌면서 빈칸의 개수를 count해준다.
		for(int i = 0; i < N; i++) {
			for(int j = 0; j < M; j++) {
				
				if(tmp[i][j] == 0)
					result++;
			}
		}
		
		return result;
	}

}
  1. 바이러스 좌표만 Queue에 담아서 탐색하는 경우
import java.util.*;
import java.io.*;

public class Main {
	
	static int N;
	static int M;
	static int map[][];
	static int[] moveX = {1, -1, 0, 0};
	static int[] moveY = {0, 0, 1, -1};
	static int answer;
	
	static ArrayList<Node> virus = new ArrayList<>();
	
	public static class Node{
		int x;
		int y;
		
		public Node(int x, int y) {
			this.x = x;
			this.y = y;
		}
	}

	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];
		answer = 0;
		
		for(int i = 0; i < N; i++) {
			st = new StringTokenizer(br.readLine(), " ");
			for(int j = 0; j < M; j++) {
				map[i][j] = Integer.parseInt(st.nextToken());
				if(map[i][j] == 2) {
					virus.add(new Node(i, j));
				}
			}
		}
		dfs(0);
		System.out.println(answer);
	}
	
	public static void dfs(int count) {
		if(count == 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(count+1);
					map[i][j] = 0;
				}
			}
		}
	}
	
	public static void bfs() {
		
		boolean check[][] = new boolean[N][M];
		int copyMap[][] = new int[N][M];
		Queue<Node> q = new LinkedList<>();
		
		// 1. 배열 복사
		for(int i = 0; i < N; i++) {
			for(int j = 0; j < M; j++) {
				copyMap[i][j] = map[i][j];
			}
		}
		
		for(Node node : virus) {
			q.add(node);
			check[node.x][node.y] = true;
		}
		
		while(!q.isEmpty()) {
			Node node = q.poll();
			int x = node.x;
			int y = node.y;
			
			for(int i = 0; i < 4; i++) {
				int goX = x + moveX[i];
				int goY = y + moveY[i];
				
				if(goX < 0 || goY < 0 || goX >= N || goY >= M)
					continue;
				
				if(copyMap[goX][goY] != 0 || check[goX][goY])
					continue;
				
				check[goX][goY] = true;
				copyMap[goX][goY] = 2;
				q.add(new Node(goX, goY));
			}
		}
		
		int count = 0;
		for(int i = 0; i < N; i++) {
			for(int j = 0; j < M; j++) {
				if(copyMap[i][j] == 0)
					count++;
			}
		}
		answer = Math.max(answer, count);
	}

}

0개의 댓글

관련 채용 정보