BOJ] 14502. 연구소
https://www.acmicpc.net/problem/14502
14502번: 연구소
인체에 치명적인 바이러스를 연구하던 연구소에서 바이러스가 유출되었다. 다행히 바이러스는 아직 퍼지지 않았고, 바이러스의 확산을 막기 위해서 연구소에 벽을 세우려고 한다. 연구소는 크기가 N×M인 직사각형으로 나타낼 수 있으며, 직사각형은 1×1 크기의 정사각형으로 나누어져 있다. 연구소는 빈 칸, 벽으로 이루어져 있으며, 벽은 칸 하나를 가득 차지한다. 일부 칸은 바이러스가 존재하며, 이 바이러스는 상하좌우로 인접한 빈 칸으로 모두 퍼져나갈 수 있다.
www.acmicpc.net
2017년 SW역량테스트 기출문제
풀었던 문제지만, 떠올릴 겸 다시 풀어보았다.
생각보다 막힌 부분이 있었지만 알고리즘을 배우고 나서 다시 보니 느낌이 다르다.
브루트포스 + DFS의 형태의 문제로 해석하여 풀었다.
특히 이 문제를 통해서 알고가야 할 것은
'2차원 배열에서의 조합' 과 '벽을 세우고 다시 원상복귀 시키는 행위'이다. 
이것만 잘 고려했다면, 쉬운 문제겠지만 난 이게 어려웠었다.
연구소 문제 시리즈는 여러모로 배울 점이 많은 문제들이다.( 연구소3도 많이 배웠다.)
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | import java.util.ArrayList; import java.util.Scanner; public class boj14502_연구소 {     static class POS {         int r;         int c;         public POS(int r, int c) {             this.r = r;             this.c = c;         }     }     static int R;     static int C;     static int AREA;     static int[][] map;     static int[][] copy;     static ArrayList<POS> VirusList = new ArrayList<POS>();     static int[] dr = {-1,1,0,0};     static int[] dc = {0,0,-1,1};     public static void main(String[] args) {         Scanner sc = new Scanner(System.in);         R = sc.nextInt();         C = sc.nextInt();         map = new int[R][C];         copy = new int[R][C];         // 초기 연구소 상태 입력 및 모든 바이러스 위치 저장          for (int i = 0; i < R; i++) {             for (int j = 0; j < C; j++) {                 map[i][j] = sc.nextInt();                 if(map[i][j]==2)                     VirusList.add(new POS(i,j));             }         }         setWall(0,0);         System.out.println(AREA);     }     static void setWall(int start, int depth) {         //벽을 모두 세운 경우          if(depth==3) {             // 바이러스를 퍼뜨려 볼 벽을 복사             copyMap();             // 바이러스 퍼뜨리기             for(POS p : VirusList) {                 // dfs                  SpreadVirus(p.r, p.c);             }             // 안전지역 카운팅하기             // 최대값과 비교하기              AREA = Math.max(AREA, SafeArea());             return;         }         //2차원 배열에서의 조합.         for(int i=start; i<R*C; i++) {             int r = i/C;             int c = i%C;             //초기 지도에서 빈 공간이었다면.             if(map[r][c]==0) {                 //벽을 세워본다.                 map[r][c]=1;                 setWall(i+1, depth+1);                 //원상복귀                  map[r][c]=0;             }         }     }     static void SpreadVirus(int r, int c) {         for(int d=0; d<4; d++) {             int nr = r + dr[d];             int nc = c + dc[d];             // 배열범위 확인              if(nr<0 || nc<0 || nr >= R || nc >= C) continue;             // 빈 공간이라면,바이러스 전파.             if(copy[nr][nc]==0) {                 copy[nr][nc]=2;                 SpreadVirus(nr, nc);             }         }     }     static int SafeArea() {         int total =0;         for(int i=0; i<R; i++) {             for(int j=0; j<C; j++) {                 if(copy[i][j]==0)                     total++;             }         }         return total;      }     static void copyMap() {         for (int i = 0; i < R; i++) {             for (int j = 0; j < C; j++) {                 copy[i][j] = map[i][j];             }         }     }// end copyMap method } | cs | 
'Algorithm > BOJ' 카테고리의 다른 글
| BOJ] 2805. 나무 자르기 (0) | 2019.10.05 | 
|---|---|
| BOJ] 4179. 불! (0) | 2019.10.05 | 
| BOJ] 16283. Farm (0) | 2019.10.01 | 
| BOJ] 2579. 계단오르기 (0) | 2019.09.25 | 
| BOJ] 1003. 피보나치 함수 (0) | 2019.09.24 |