Algorithm/백준

[BOJ] - 17144. 미세먼지 안녕!

benguin 2019. 6. 25. 15:25

[URL]

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

 

17144번: 미세먼지 안녕!

미세먼지를 제거하기 위해 구사과는 공기청정기를 설치하려고 한다. 공기청정기의 성능을 테스트하기 위해 구사과는 집을 크기가 R×C인 격자판으로 나타냈고, 1×1 크기의 칸으로 나눴다. 구사과는 뛰어난 코딩 실력을 이용해 각 칸 (r, c)에 있는 미세먼지의 양을 실시간으로 모니터링하는 시스템을 개발했다. (r, c)는 r행 c열을 의미한다. 공기청정기는 항상 왼쪽 열에 설치되어 있고, 크기는 두 행을 차지한다. 공기청정기가 설치되어 있지 않은 칸에는 미세먼

www.acmicpc.net

[풀이 과정]

* 시뮬레이션

1. input() -> map[][]정보값 입력 받는다.

  // 미세먼지면 벡터에 저장

 

2. t초 만큼 for문 돌면서 계산

  // 1) spread(); 벡터의 크기만큼 돌면서 해당 미세먼지값을 4방향으로 확산시킨다.

  // 2) cleanerON(); 공기청정기 작동, 위쪽, 아래쪽 두개로 나누어서 계산

  // 3) reset();  벡터, spreadMap 초기화! 

 

3. 남아있는 미세먼지 계산 dap 출력!

 

[소스 코드]

 

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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
#include <stdio.h>
#include <vector>
using namespace std;
 
int R, C, T;
int map[51][51];
int spreadMap[51][51= { 0, };
int up = -1, down = -1;        // 청소기 윗부분, 아래부분
int dap = 0;
 
int dx[] = { 00-11 };
int dy[] = { -1100 };
 
struct dust {
    int x;
    int y;
    int val;
};
vector <dust> V;
 
void input() {
    scanf("%d %d %d"&R, &C, &T);
 
    for (int i = 0; i < R; i++)
    {
        for (int j = 0; j < C; j++)
        {
            scanf("%d"&map[i][j]);
            if (map[i][j] != 0 && map[i][j] != -1)
            {
                dust temp;
                temp.x = i;
                temp.y = j;
                temp.val = map[i][j];
 
                V.push_back(temp);
            }
            if (map[i][j] == -1) {
                down = i;
            }
        }
    }
 
    for (int i = 0; i < R; i++)
    {
        for (int j = 0; j < C; j++)
        {
            if (map[i][j] == -1)
            {
                up = i;
            }
        }
        if (up != -1)
        {
            break;
        }
    }
}
 
void spread(int cx, int cy, int val)
{
    int spreadCnt = 0;        // 가능한 방향 개수
 
    for (int k = 0; k < 4; k++)
    {
        int nx = cx + dx[k];
        int ny = cy + dy[k];
 
        if (nx >= 0 && nx < R && ny >= 0 && ny < C && map[nx][ny] != -1)        // nx, ny 범위 안에 있는 경우! + 공기청정기 아닌 경우
        {
            spreadCnt++;
            spreadMap[nx][ny] += val / 5;
        }
    }
    spreadMap[cx][cy] += val - ((val / 5)*spreadCnt);
}
 
void cleanerON() {
    //UpSide: 반시계방향 작동 
    for (int i = 0; i <= up; i++)
    {
        for (int j = 0; j < C; j++)
        {
            int tempVal = spreadMap[i][j];
            if (i >= 1 && j >= 1 && i <= up - 1 && j <= C - 2)
            {
                map[i][j] = tempVal;
            }
            else
            {
                if (j == 0 && i != up)
                {
                    map[i + 1][j] = tempVal;
                }
                if (i == 0 && j != 0)
                {
                    map[i][j - 1= tempVal;
                }
                if (j == C - 1 && i != 0)
                {
                    map[i - 1][j] = tempVal;
                }
                if (i == up && j != C - 1)
                {
                    map[i][j + 1= tempVal;
                }
            }
        }
    }
    map[up][0= -1;
 
    //DownSide: 시계방향 작동 
    for (int i = down; i < R; i++)
    {
        for (int j = 0; j < C; j++)
        {
            int tempVal = spreadMap[i][j];
 
            if (i >= down + 1 && j >= 1 && i <= R - 2 && j <= C - 2)
            {
                map[i][j] = tempVal;
            }
            else
            {
                if (j == 0 && i != down)
                {
                    map[i - 1][j] = tempVal;
                }
                if (i == down && j != C - 1)
                {
                    map[i][j + 1= tempVal;
                }
                if (j == C - 1 && i != R - 1)
                {
                    map[i + 1][j] = tempVal;
                }
                if (i == R - 1 && j != 0)
                {
                    map[i][j - 1= tempVal;
                }
            }
        }
    }
    map[down][0= -1;
}
 
void reset() {
    for (int i = 0; i < R; i++)
    {
        for (int j = 0; j < C; j++)
        {
            spreadMap[i][j] = 0;
        }
    }
 
    V.clear();        // 벡터 모든 원소 클리어!
    for (int i = 0; i < R; i++)
    {
        for (int j = 0; j < C; j++)
        {
            if (map[i][j] != -1 && map[i][j] != 0)
            {
                dust temp;
                temp.x = i;
                temp.y = j;
                temp.val = map[i][j];
 
                V.push_back(temp);
            }
        }
    }
}
 
int main() {
 
    input();
 
    for (int t = 0; t < T; t++)            //t초 만큼 진행 사항 계산
    {
        //1. 미세먼지 확산: 결과 spreadMap[][]에 저장
        for (int i = 0; i < V.size(); i++)
        {
            spread(V[i].x, V[i].y, V[i].val);    // 4방향 확산 (방향, 가능한지, 양 check)
        }
        //2. 공기청정기 작동
        cleanerON();        
        // 3. 초기화: spreadMap[][] = 0, 벡터 = 새로 확산된 먼지로 업데이트
        reset();
    }
 
    for (int i = 0; i < R; i++)
    {
        for (int j = 0; j < C; j++)
        {
            if (map[i][j] != -1 && map[i][j] != 0)
            {
                dap += map[i][j];
            }
        }
    }
 
    printf("%d\n", dap);
 
    return 0;
}
cs

'Algorithm > 백준' 카테고리의 다른 글

[BOJ] - 14502. 연구소  (0) 2019.07.03
[BOJ] - 2156. 포도주 시식  (0) 2019.07.01
[BOJ] - 2178. 미로 탐색  (0) 2019.06.20
[BOJ] - 2309. 일곱 난쟁이  (0) 2019.06.11
[BOJ] - 14503. 로봇 청소기  (0) 2019.04.13