문제 링크
삼성 SW 역량테스트 기출 백준 연구소 14502
문제 조건
연구소는 크기가 N×M
입니다.
연구소에서 빈곳 0, 벽 1, 바이러스 2
의 값이 주어지게 됩니다.
벽을 3개만 세운 뒤 바이러스가 퍼질 수 없는 안전영역의 최댓값을 구하는 문제입니다.
지도의 세로 크기 N과 가로 크기 M (3 ≤ N, M ≤ 8)
컴퓨팅 사고
0은 빈 칸, 1은 벽, 2는 바이러스가 있는 곳이다. 아무런 벽을 세우지 않는다면, 바이러스는 모든 빈 칸으로 퍼져나갈 수 있다.
라는 조건이 있는 문제입니다.
이 문제를 풀때 가장 중요한점은 DFS로 접근해야 하는가? BFS로 접근해야 하는가를 많이 고민하였던 문제였습니다.
Basement 조건이 벽을 3개
세울 때 조합의 경우의 수를 사용하기 위해서 DFS를 사용하였으며, 연구소에서 바이러스들이 전염시키는 과정은 BFS로 풀이를 진행하였습니다.
값을 입력받고 빈칸과 바이러스의 좌표를 담고 있는 벡터에 해당 값들을 넣어주게 됩니다.
빈칸을 기준으로 DFS를 수행한다. 따라서,조합의 경우라고 생각하면 됩니다. N(빈칸의 개수중)에서 3개를 뽑는 경우의 수라고 생각을 합니다.
DFS 에서의 수행은 빈칸의 개수가 기준이 되므로 empty_size를 선언해서 받아오게 하였습니다.
CNT 값이 3일 경우 3개의 벽을 모두 세운 경우이므로 기존의 값은 변화가 되면 안되기때문에 맵을 Copy시켜줍니다.
이제 BFS를 수행하기위해 각각의 경우에 있어서 Check변수가 1일 경우에만 벽을 세워주게 됩니다.
바이러스가 전파시에 현재 바이러스의 값 2
인 좌표 (x,y)의 점을 기준으로 BFS
를 수행합니다.
모든 BFS경우를 돌고나서 아직 전염되지 않은 값이 있는곳이 안전지대
입니다. 그 곳의 값을 safe_size 카운팅
시켜줍니다.
각 경우마다 안전영역의 최대의 값을 구해주어야하므로 최댓값을 갱신시켜줍니다.
각 경우마다 경우의 수가 달라지므로 visited 변수를 초기화 시켜줍니다.
즉, DFS 반복 → basement 확인 → BFS (x,y)좌표로 부터 바이러스 전염 → 안전영역의 최댓값
다시 풀어보았습니다.
(1) N*M의 보드가 주어집니다. (3 ≤ N, M ≤ 8)의 범위를 갖습니다.
바이러스의 확산의 벽을 3개를 세워야합니다.
맵에서 벽을 3개를 세우는 경우를 어떻게 찾아낼까가 가장 핵심이 되는 문제였습니다. 저 같은 경우는 하나의 리스트에 x,y좌표를 담고있는 Graph클래스를 하나 선언하여 ‘0’ 즉, 빈칸의 좌표값을 모두 리스트에 담아주었습니다. 그리고나서 DFS 백트래킹을 통하여 N개(모든 빈칸의 리스트)중에서 M개(3개를 선택) 하는 경우의 순열의 값들을 모두 구해주게 하였습니다. 예를 들어, 안전영역리스트에 1,2,3,4,5 가 주어졌다고 가정하면 여기서 벽을 세우는 경우는 어떻게 될까요? (1,2,3), (1,2,4),(1,2,5),(2,3,4) …. 등 다양한 경우의수가 나올 수 있게됩니다. 이 경우를 모두 체크해나갈 수 있습니다. 그리고 주의해야할 경우는 벽을 3개 모두세웠을 경우 현재 맵의 정보들이 변화하면 안되기때문에 각 경우의수마다 새로 배열들을 copy하여 갱신시켜서 매 경우를 체크해나가야합니다.
(2) 0:빈칸, 1:벽, 2:바이러스 벽이 세워지고 바이러스가 상하좌우로 퍼져나가게 합니다.
(3) 최종적인 프로세스는 벽을 3개 세우는 모든 경우의 수를 찾아주고 각 경우마다 벽을 세우고나서 바이러스를 퍼트립니다. 그리고 안전영역에 있는 최댓값 갱신해나가면 정답을 노출해낼 수 있습니다. 전반적으로 한번 풀어봤던 경험이 있었던지라 30분정도 소요되었던 문제였습니다.
(4) 순열과 조합을 각각 돌려서 테스트해보았더니 큰 차이를 얻을 수 있었습니다.

약 공간복잡도 메모리차이가 2배이상차이가나고, 시간복잡도 차이에서는 1.5배이상 차이가 나게되었습니다. 확실히 순열로 돌리게 될 경우 상당히 많은 경우의 수가 나타난다는것을 알 수 있었습니다.
제출 번호 아이디 문제 결과 메모리 시간 언어 코드 길이
28575832 kgh940525 14502 맞았습니다!! 149348 636 Java 8 / 수정 5431
28575134 kgh940525 14502 맞았습니다!! 303684 1000 Java 8 / 수정 4086
풀이 코드
JAVA 재풀이 코드
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 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 package Samsung.ing;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.*;public class 연구소_14502 번 { static int n,m; static int answer; static int [][] map; static int [][] copyMap; static int [][] dir = {{-1 ,0 },{0 ,1 },{1 ,0 },{0 ,-1 }}; static boolean [] isCheckSafe; static boolean [][] isCheckVirus; static List<Graph> safeAreaList; static List<Graph> safeAreaSelectList; 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 ; safeAreaList = new ArrayList<>(); safeAreaSelectList = new ArrayList<>(); int idx = 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] == 0 ){ safeAreaList.add(new Graph(i,j)); } } } isCheckSafe = new boolean [safeAreaList.size()]; dfs_combination(0 ,0 ); System.out.println(answer); } private static void dfs_combination (int idx, int cnt) { if (cnt == 3 ){ copyMap = new int [n][m]; isCheckVirus = new boolean [n][m]; for (int i=0 ; i<n; i++){ for (int j=0 ; j<m; j++){ copyMap[i][j] = map[i][j]; } } for (int i = 0 ; i < safeAreaList.size(); i++) { if (isCheckSafe[i]){ int safeX = safeAreaList.get(i).x; int safeY = safeAreaList.get(i).y; copyMap[safeX][safeY] = 1 ; } } for (int i=0 ; i<n; i++){ for (int j=0 ; j<m; j++){ if (copyMap[i][j] == 2 && !isCheckVirus[i][j]) { virusSpread(i,j); } } } getSafeAreaSize(); return ; } for (int i=idx; i<safeAreaList.size(); i++){ if (isCheckSafe[i]) continue ; isCheckSafe[i] = true ; dfs_combination(i,cnt+1 ); isCheckSafe[i] = false ; } } private static void dfs_permutation (int cnt) { if (cnt == 3 ){ copyMap = new int [n][m]; isCheckVirus = new boolean [n][m]; for (int i=0 ; i<n; i++){ for (int j=0 ; j<m; j++){ copyMap[i][j] = map[i][j]; } } for (int i = 0 ; i < safeAreaSelectList.size(); i++) { Graph graph = safeAreaSelectList.get(i); int x = graph.x; int y = graph.y; copyMap[x][y] = 1 ; } for (int i=0 ; i<n; i++){ for (int j=0 ; j<m; j++){ if (copyMap[i][j] == 2 && !isCheckVirus[i][j]) { virusSpread(i,j); } } } getSafeAreaSize(); return ; } for (int i=0 ; i<safeAreaList.size(); i++){ Graph graph = safeAreaList.get(i); if (isCheckSafe[i]) continue ; isCheckSafe[i] = true ; safeAreaSelectList.add(new Graph(graph.x, graph.y)); dfs_permutation(cnt+1 ); safeAreaSelectList.remove(safeAreaSelectList.size()-1 ); isCheckSafe[i] = false ; } } private static void getSafeAreaSize () { int areaSize = 0 ; for (int i = 0 ; i < n; i++) { for (int j=0 ; j< m; j++){ if (copyMap[i][j] == 0 ) areaSize++; } } answer = Math.max(answer, areaSize); } private static void virusSpread (int x,int y) { Queue<Graph> q = new LinkedList<>(); q.add(new Graph(x,y)); isCheckVirus[x][y] = true ; while (!q.isEmpty()){ Graph graph = q.remove(); int dx = graph.x; int dy = graph.y; for (int i=0 ; i<4 ; i++){ int mx = dx + dir[i][0 ]; int my = dy + dir[i][1 ]; if (isCheckRange(mx, my)) continue ; if (copyMap[mx][my] == 0 && !isCheckVirus[mx][my]){ copyMap[mx][my] = 2 ; isCheckVirus[mx][my] = true ; q.add(new Graph(mx,my)); } } } } private static boolean isCheckRange (int mx, int my) { if (mx < 0 || mx >= n || my < 0 || my >= m){ return true ; } return false ; } private static class Graph { int x; int y; public Graph (int x, int y) { this .x = x; this .y = y; } } }
C++
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 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 #include <iostream> #include <stdio.h> #include <vector> #include <queue> #include <cstring> using namespace std;int n,m = 0 ;const int MAX = 8 ;int map[MAX][MAX];int copy_map[MAX][MAX];vector<pair<int ,int >> empty; vector<pair<int ,int >> virus; int empty_size = 0 ;int check[MAX*MAX]; int visited[MAX][MAX];int dir[4 ][2 ] = {{1 ,0 },{0 ,1 },{-1 ,0 },{0 ,-1 }};int ans = -1 ;void bfs (int x,int y) { queue<pair<int ,int >> q; q.push ({x,y}); visited[x][y] = 1 ; while (!q.empty ()){ int dx = q.front ().first; int dy = q.front ().second; q.pop (); for (int i=0 ; i<4 ; i++){ int mx = dx + dir[i][0 ]; int my = dy + dir[i][1 ]; if (mx >= 0 && mx < n && my >= 0 && my < m){ if (visited[mx][my] == 0 && copy_map[mx][my] == 0 ){ visited[mx][my] = 1 ; copy_map[mx][my] = 2 ; q.push ({mx,my}); } } } } } void dfs (int idx,int cnt) { if (cnt == 3 ){ memset (visited, 0 , sizeof (visited)); for (int i=0 ; i<n; i++){ for (int j=0 ; j<m; j++){ copy_map[i][j] = map[i][j]; } } int count = 0 ; for (int i=0 ; i<empty_size; i++){ if (count == 3 ){ break ; } if (check[i] == 1 ){ int x = empty[i].first; int y = empty[i].second; copy_map[x][y] = 1 ; count +=1 ; } } for (int i=0 ; i<virus.size (); i++){ int x = virus[i].first; int y = virus[i].second; bfs (x,y); } int safe_size = 0 ; for (int i=0 ; i<n; i++){ for (int j=0 ; j<m; j++){ if (copy_map[i][j] == 0 ){ safe_size++; } } } if (ans < safe_size){ ans = safe_size; } return ; } for (int i=idx; i<empty_size; i++){ if (check[i] == 1 ){ continue ; } check[i] = 1 ; dfs (i, cnt+1 ); check[i] = 0 ; } } int main (void ) { cin >> n >> m; for (int i=0 ; i<n; i++){ for (int j=0 ; j<m; j++){ cin >> map[i][j]; if (map[i][j] == 0 ){ empty.push_back ({i,j}); } else if (map[i][j] == 2 ){ virus.push_back ({i,j}); } } } empty_size = empty.size (); dfs (0 ,0 ); cout << ans; return 0 ; }
JAVA
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 import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.ArrayList;import java.util.List;import java.util.StringTokenizer;public class 연구소 { static class Dot { private int x; private int y; public Dot (int x, int y) { this .x = x; this .y = y; } } static int n; static int m; static int [][] map; static int [][] copy_map; static List<Dot> virusList = new ArrayList<Dot>(); static int [][] dir ={{-1 ,0 },{1 ,0 },{0 ,1 },{0 ,-1 }}; static int ans = 0 ; static void wallDfs (int idx, int cnt) { if (cnt == 3 ){ copyMapFunc(); for (Dot dot : virusList){ virusSpreadBfs(dot.x, dot.y); } ans = Math.max(ans, getSafeArea()); return ; } for (int i=idx; i<n * m; i++){ int x = i / m; int y = i % m; if (map[x][y] == 1 || map[x][y] == 2 ){ continue ; } map[x][y] = 1 ; wallDfs(i+1 , cnt+1 ); map[x][y] = 0 ; } } static void copyMapFunc () { for (int i=0 ; i<n; i++){ for (int j=0 ; j<m; j++){ copy_map[i][j] = map[i][j]; } } } static void virusSpreadBfs (int x,int y) { for (int i=0 ; i<4 ; i++){ int mx = x + dir[i][0 ]; int my = y + dir[i][1 ]; if (mx >= 0 && mx < n && my >= 0 && my < m){ if (copy_map[mx][my] == 0 ){ copy_map[mx][my] = 2 ; virusSpreadBfs(mx,my); } } } } static int getSafeArea () { int safe = 0 ; for (int i=0 ; i<n; i++){ for (int j=0 ; j<m; j++){ if (copy_map[i][j] == 0 ){ safe += 1 ; } } } return safe; } 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]; copy_map = new int [n][m]; 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 ){ virusList.add(new Dot(i,j)); } } } wallDfs(0 ,0 ); System.out.println(ans); } }