본문 바로가기

BOJ/C++

[BOJ] 연구소

[문제]

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

 

14502번: 연구소

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

www.acmicpc.net

[풀이]

14502 맞았습니다!! 1988 KB 36 ms C++14 / 수정 2189 B 1분 전

 

1) 너비우선탐색 문제

 

2) 새로운 벽을 3개 세워야 한다.  여기서 조합을 생각했음

 

3) dfs로 벽 3개의 조합을 만들고, spreadVirus에서 큐를 이용하여 완전 탐색한다. 

 

4) 맵이 변형되기 때문에 맵을 복사 후에 바이러스를 퍼트리고 그 때의 안전 공간의 최대 값을 구해야 한다. 


 

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
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
 
using namespace std;
//풀이 : 25분 
 
int n, m, map[9][9], max_safe = 0;
bool visited[9][9];
typedef pair<intint> pp;
 
vector<pp> virus;
 
int dx[4= {00-11}, dy[4= {-1100};
 
void printMap()
{
    cout << '\n';
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            cout << map[i][j] << " ";
        }
        cout << '\n';
    }
    cout << '\n';
}
void spreadVirus()
{
    queue<pp> q;
 
    memset(visited, falsesizeof(visited));
 
    for (int i = 0; i < virus.size(); i++)
    {
        q.push(virus[i]);
        visited[virus[i].first][virus[i].second];
    }
 
    while (!q.empty())
    {
        int size = q.size();
 
        while (size--)
        {
 
            int x = q.front().first;
            int y = q.front().second;
            q.pop();
 
            for (int i = 0; i < 4; i++)
            {
                int nx = x + dx[i];
                int ny = y + dy[i];
 
                if (nx < 0 || nx >= n || ny < 0 || ny >= m || visited[nx][ny])
                    continue;
 
                if (map[nx][ny] == 1)
                    continue;
                else if (map[nx][ny] == 2)
                    continue;
                else
                {
                    //3으로 표시 (바이러스가 퍼진 영역 )
                    map[nx][ny] = 3;
                    visited[nx][ny] = true;
                    q.push(pp(nx, ny));
                }
            }
        }
    }
 
    int safe = 0;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            if (map[i][j] == 0) safe++;
        }
    }
 
    if (max_safe < safe) max_safe = safe;
 
   
}
void dfs(int cnt)
{
    if (cnt == 3)
    {
        int c_map[9][9];
        memcpy(c_map, map, sizeof(map));
 
        //3개의 벽을 다 세움
       
        spreadVirus();
        
        memcpy(map, c_map, sizeof(c_map)); //맵 원상 복구
 
        return;
    }
 
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            if (!map[i][j])
            {
                map[i][j] = 1;
                dfs(cnt + 1);
                map[i][j] = 0;
            }
        }
    }
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
 
    cin >> n >> m;
 
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            cin >> map[i][j];
            // c_map[i][j] = map[i][j];
 
            if (map[i][j] == 2)
            {
                virus.push_back(pp(i, j));
            }
 
        }
    }
    //input
 
    dfs(0); //벽 세우기
 
    cout << max_safe << '\n';
    return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter

'BOJ > C++' 카테고리의 다른 글

[BOJ] 연산자 끼워넣기  (0) 2019.08.07
[BOJ] 구슬탈출2  (0) 2019.08.07
[BOJ] 로봇청소기  (0) 2019.08.06
[BOJ] 치킨배달  (0) 2019.08.06
[BOJ] 드래곤커브  (0) 2019.08.06