[BOJ] 14502번: 연구소

2023. 3. 5. 22:49·Problem Solving/Baekjoon

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

 

 

14502번: 연구소

인체에 치명적인 바이러스를 연구하던 연구소에서 바이러스가 유출되었다. 다행히 바이러스는 아직 퍼지지 않았고, 바이러스의 확산을 막기 위해서 연구소에 벽을 세우려고 한다. 연구소는 크

www.acmicpc.net

 

 

 

1. 문제 설명 

상,하,좌,우로 확산되는 바이러스를 막기 위해 3개의 벽을 활용해서 안전 영역의 최대 크기를 구하는 문제이다.

 

 


2. 접근 방식 

백트래킹 + BFS로 풀었다. 생각보다 쉬웠던 문제였던 것 같다. 코드길이는 좀 길긴하지만 크게 막힘이 없었다.

 

 


3. 주석 달기 (변수 설명, 각 줄마다 문장으로 설명, 함수 설명)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class Main {
    static class Pair {
        int x;
        int y;
        public Pair(int _x, int _y) {
            x = _x;
            y = _y;
        }
    }
    static int N, M;
    static int[][] dir = {{0,1}, {0,-1}, {1,0},{-1,0}}; // 상,하,좌,우 확산
    static int[][] grid;
    static int mx = Integer.MIN_VALUE;
    static boolean[][] visit;
    static List<Pair> virusPos = new ArrayList<>();
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static void input() throws IOException {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken()); M = Integer.parseInt(st.nextToken());
        grid = new int[N][M];
        visit = new boolean[N][M];
        for(int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            for(int j = 0; j < M; j++) {
                int num = Integer.parseInt(st.nextToken());
                if (num == 1) 
                    visit[i][j] = true; // 벽 방문처리
                else if (num == 2) 
                    virusPos.add(new Pair(i,j)); // 바이러스가 위치한 좌표 저장
                
                grid[i][j] = num;
            }
        }
    }
    static void init(int[][] virtualGrid, boolean[][] virtualVisit, List<Pair> virtualList) {
        for(int i = 0; i < N; i++) {
            for(int j = 0; j < M ; j++) {
                virtualGrid[i][j] = grid[i][j];
                virtualVisit[i][j] = visit[i][j];
            }
        }
        for(Pair pair : virusPos) {
            virtualList.add(new Pair(pair.x, pair.y));
        }
    }
    
    static void rec_func(int wall) {
        if(wall == 3) {
            int[][] virtualGrid = new int[N][M];
            boolean[][] virtualVisit = new boolean[N][M];
            List<Pair> virtualList = new ArrayList<>();
            
            // 초기화 
            init(virtualGrid, virtualVisit, virtualList);
            // 바이러스 발산
            spreadVirus(virtualGrid, virtualVisit, virtualList);
            // 최대값 갱신
            mx = Math.max(mx,safety(virtualGrid));
        }
        else {
            for(int i = 0; i < N; i++) {
                for(int j = 0; j < M; j++) {
                    if(grid[i][j] == 2 || grid[i][j] == 1) continue;
                    if(visit[i][j]) continue;
                    grid[i][j] = 1;
                    visit[i][j] = true;
                    rec_func(wall + 1);
                    grid[i][j] = 0;
                    visit[i][j] = false;
                }
            }
        }
    }

    private static void spreadVirus(int[][] virtualGrid, boolean[][] virtualVisit, List<Pair> virtualVirusPos) {
        Queue<Pair> q = new LinkedList<>(); // 바이러스 BFS로 확산.
        for(Pair pair : virtualVirusPos) {
            q.add(new Pair(pair.x, pair.y));
            virtualVisit[pair.x][pair.y] = true;
        }
        while (!q.isEmpty()) {
            Pair tmpPair = q.poll();
            for(int i = 0; i < 4; i++) {
                int nx = tmpPair.x + dir[i][0];
                int ny = tmpPair.y + dir[i][1];
                if(nx < 0 || nx >= N || ny < 0 || ny >= M) continue;
                if(virtualVisit[nx][ny]) continue;
                if(virtualGrid[nx][ny] == 1 || virtualGrid[nx][ny] == 2) continue;
                virtualGrid[nx][ny] = 2;
                virtualVisit[nx][ny] = true;
                q.add(new Pair(nx,ny));
            }
        }
    }

    private static int safety(int[][] virtualGrid) {
        int ans = 0;
        for(int i = 0; i < N; i++) 
            for(int j = 0; j < M; j++) 
                if(virtualGrid[i][j] == 0) 
                    ans++;
        
        return ans;
    }

    public static void main(String[] args) throws IOException{
        input();
        rec_func(0);
        System.out.println(mx);
    }
}

 

 


4. 분석 및 시간복잡도

 시간복잡도 : 중복순열(N^N) * BFS(N*2*4) ..?

'Problem Solving/Baekjoon' 카테고리의 다른 글
  • [BOJ] 3085번: 사탕 게임
  • [BOJ] 1476번: 날짜 계산
  • [BOJ] 14926번: Not Equal
  • [BOJ] 1753번: 최단경로
kimdozzi
kimdozzi
끝까지 포기하지 않으면, 내가 다 이겨!
  • kimdozzi
    도브로
    kimdozzi
  • 전체
    오늘
    어제
    • 분류 전체보기 (132)
      • Problem Solving (49)
        • Baekjoon (29)
        • Programmers (0)
        • LeetCode (17)
        • 삼성 유형 (2)
      • Computer Science (27)
        • Operating System (2)
        • Algorithms (13)
        • Network (6)
        • DataBase (6)
      • Backend (33)
        • JavaScript (0)
        • TypeScript (6)
        • Java (7)
        • Spring Boot (7)
        • Spring Security (6)
        • JPA (2)
        • Mybatis (1)
        • Junit5 (1)
        • Redis (3)
      • DevOps (14)
        • Git, Github (5)
        • docker (4)
        • AWS (3)
        • nginx (2)
      • etc (6)
        • IntelliJ (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
    • 티스토리
    • 설정
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    오블완
    누적합
    docker image
    오프라인 쿼리
    세그먼트 트리
    S3
    인덱스 시그니처
    알고리즘
    온라인 쿼리
    인터페이스
    Bucket
    interface
    AWS
    docker
    PrefixSum
    삼성기출
    도커
    구간 업데이트
    구간합
    TypeScript
    imos법
    python
    컨테이너
    티스토리챌린지
    CORS
    백준
    segment tree
    인덱서블 타입
    파이썬
    점 업데이트
    타입스크립트
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
kimdozzi
[BOJ] 14502번: 연구소
상단으로

티스토리툴바