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

 

14502번: 연구소

인체에 치명적인 바이러스를 연구하던 연구소에서 바이러스가 유출되었다. 다행히 바이러스는 아직 퍼지지 않았고, 바이러스의 확산을 막기 위해서 연구소에 벽을 세우려고 한다. 연구소는 크기가 N×M인 직사각형으로 나타낼 수 있으며, 직사각형은 1×1 크기의 정사각형으로 나누어져 있다. 연구소는 빈 칸, 벽으로 이루어져 있으며, 벽은 칸 하나를 가득 차지한다.  일부 칸은 바이러스가 존재하며, 이 바이러스는 상하좌우로 인접한 빈 칸으로 모두 퍼져나갈 수 있다.

www.acmicpc.net

이 문제를 해결하는데 필요한 알고리즘 : BFS or Brute force (or DFS)

나는 BFS로 풀었다.

처음에는 배열의 크기를 생각하지 못하고 시간초과 없이 어떻게 해결해야하나 했는데

8*8 크기라면 전범위를 다돌아도 괜찮을 것 같았다.

바이러스가 없는 0 부분에 1을 2칸 집어넣고 1칸씩 옮겨가면서 경우의 수를 다 구해줬다.

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
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
 
int arr[8][8];
int ans[8][8];
int Arr[8][8];
int temp[4= { -1,1,0,0 };
int temp2[4= { 0,0,-1,1 };
typedef pair<intint> pii;
vector<pii> v;
int MAX, first, second;
int N, M, virus;
bool visit;
bool check[8][8];
 
void dfs(int n, int m) { // n -> 세로 m -> 가로
 
    for (int i = 0; i < 4; i++) {
        if (n + temp[i] >= 0 && n + temp[i] < N && m + temp2[i] >= 0 && m + temp2[i] < M) {
            if (arr[n + temp[i]][m + temp2[i]] == 0) {
                arr[n + temp[i]][m + temp2[i]] = 2;
                dfs(n + temp[i], m + temp2[i]);
            }
        }
    }
 
}
 
void lab() {
 
    if (virus == 3) {
        int zero = 0;
        for (int i = 0; i < N; i++)
            for (int j = 0; j < M; j++)
                ans[i][j] = arr[i][j];
        for (int i = 0; i < v.size(); i++) {
            dfs(v[i].first, v[i].second);
        }
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                if (arr[i][j] == 0) zero++;
                arr[i][j] = ans[i][j];
                ans[i][j] = Arr[i][j];
            }
        }
        MAX = max(MAX, zero);
        return;
    }
 
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            if (i == N-1 && j == M-1
                visit = true;
            if (arr[i][j] == 0) {
                if (!check[i][j]) {
                    if (virus == 1)
                        check[i][j] = true, first = i, second = j;
                    arr[i][j] = 1, virus++;
                    lab();
                    if (i != first || j != second)
                        arr[i][j] = 0, virus--;
                }
            }
            if (visit == true) {
                if (i == first && j == second) {
                    visit = false;
                    if (first != N - 1 || second != M - 1) {
                        arr[first][second] = 0, virus--;
                        if (second != M - 1) {
                            j = second;
                        }
                        else {
                            i = first;
                            j = -1;
                        }
                    }
                }
                else return;
            }
        }
    }
}
 
int main() {
    cin >> N >> M;
 
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            cin >> arr[i][j];
            Arr[i][j] = arr[i][j];
            if (arr[i][j] == 2) v.push_back(make_pair(i, j));
        }
    }
 
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            if (arr[i][j] == 0) {
                arr[i][j] = 1, virus = 1, visit = false;
                lab();
                if (Arr[N - 1][M - 1!= 1)
                    if (arr[N - 1][M - 1== 1) arr[N - 1][M - 1= 0;
                arr[i][j] = 0;
            }
            for (int i = 0; i < N; i++)
                for (int j = 0; j < M; j++)
                    check[i][j] = false;
        }
    }
 
    cout << MAX;
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter

'algorithm > BOJ' 카테고리의 다른 글

6603번 : 로또 - junnnho  (0) 2019.04.07
1182번 : 부분수열의 합 - junnnho  (0) 2019.04.07
16235번 : 나무제테크 - Junnnho  (0) 2019.04.07
BOJ 1463번 1로 만들기  (0) 2019.04.07
BOJ 1965번 상자넣기  (0) 2019.04.07

+ Recent posts