조합 + 탐색 문제
재귀를 통해서 활성시킬 바이러스를 선택 후 BFS를 통해 바이러스를 확산시켜 된다.
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 | #include <iostream> #include <queue> #include <string.h> #include <vector> #include <algorithm> using namespace std; int map[50][50], visit[50][50], arr[50][50]; int drc[] = { 0,0,-1,1,-1,1,0,0 }; int N, M, safeArea, ans = 1e9; struct pnt { int r, c; }; vector<pnt>virus; queue<pnt>Q; bool sel[10]; bool chk(int r, int c) { if (!(r < 0 || c < 0 || r >= N || c >= N)) return true; return false; } void bfs() { int tmp = 0; int area = safeArea; while (!Q.empty()) { int r = Q.front().r; int c = Q.front().c; Q.pop(); for (int d = 0; d < 4; d++) { int nr = r + drc[d]; int nc = c + drc[d + 4]; if (chk(nr, nc) && map[nr][nc] != 1 && visit[nr][nc] == -1) { visit[nr][nc] = visit[r][c] + 1; Q.push({ nr,nc }); if (map[nr][nc] == 0) { tmp = max(tmp, visit[nr][nc]); area--; } if (area == 0) break; } } } if(area == 0) ans = min(tmp, ans); } void selvirus(int cnt,int idx) { if (cnt == M) { memset(visit, -1, sizeof(visit)); for (int i = 0; i < virus.size(); i++) { int r = virus[i].r; int c = virus[i].c; if (sel[i] == true) { Q.push({ r,c }); visit[r][c] = 0; } } bfs(); return; } for (int i = idx; i < virus.size(); i++) { if (sel[i] == true) continue; sel[i] = true; selvirus(cnt + 1, i + 1); sel[i] = false; } } int main() { ios::sync_with_stdio(0), cin.tie(0); cin >> N >> M; for (int r = 0; r < N; r++) { for (int c = 0; c < N; c++) { cin >> map[r][c]; if (map[r][c] == 0) safeArea++; else if (map[r][c] == 2) virus.push_back({ r,c }); } } selvirus(0, 0); if (ans == 1e9) ans = -1; cout << ans; return 0; } | cs |
'백준 > [삼성 기출]' 카테고리의 다른 글
[17472번] 다리 만들기2 (0) | 2020.04.11 |
---|---|
[3190번] 뱀 (0) | 2020.04.04 |
[13460번] 구슬 탈출 2 (0) | 2020.04.04 |
[16637번] 괄호 추가하기 (0) | 2020.04.04 |
[16235번] 나무 재테크 (0) | 2020.03.01 |
댓글