[백준/C++]: 17144번 미세먼지 안녕!
https://www.acmicpc.net/problem/17144
17144번: 미세먼지 안녕!
미세먼지를 제거하기 위해 구사과는 공기청정기를 설치하려고 한다. 공기청정기의 성능을 테스트하기 위해 구사과는 집을 크기가 R×C인 격자판으로 나타냈고, 1×1 크기의 칸으로 나눴다. 구사
www.acmicpc.net
문제해석
공기청정기 코드 생성하고, 반복문으로 계속 이동하며 공기청정기가 있는 곳에 먼지 분포가 안 되게끔 해야한다.
미세먼지 각각들을 칸으로 나눠서 그 칸에 입력 받았으면 행 +1,-1 열 +1,-1 나눠져서 /5한값이 이동되는거 저장 해줘야한다.(이때 카운트 처리)
주의 : 맨 처음 행,열 맨 나중 행,열에 있을 경우는 확산될수 없다는 if 조건문을 달아서 처리해줘야한다. (이때 카운트 처리X)
그리고 확산 되면 본래의 미세먼지 값에서 확산 된 만큼의 값을 제거해줘야한다.
총 미세먼지를 더해놓고 바뀌어지는 미세먼지 값들을 계속해서 업데이트 시켜줘야 한다.(공기청정기로 인해 먼지가 사라짐.)
코드
#include <iostream>
using namespace std;
int R, C, T;
int r[51][51];
int a[51][51];
int upconditioner=0, downconditioner=0;
int dust_total=0;
int rr[] = {0,1,0,-1};
int cc[] = {-1,0,1,0};
void conditioner() {
dust_total -= r[upconditioner - 1][0];
dust_total -= r[downconditioner + 1][0];
for (int i = upconditioner - 1; i > 0; i--)
r[i][0] = r[i - 1][0];
for (int i = 0; i < C - 1; i++)
r[0][i] = r[0][i + 1];
for (int i = 1; i <= upconditioner; i++)
r[i - 1][C - 1] = r[i][C - 1];
for (int i = C - 1; i > 1; i--)
r[upconditioner][i] = r[upconditioner][i - 1];
r[upconditioner][1] = 0;
for (int i = downconditioner + 1; i < R - 1; i++)
r[i][0] = r[i + 1][0];
for (int i = 0; i < C - 1; i++)
r[R - 1][i] = r[R - 1][i + 1];
for (int i = R - 1; i >= downconditioner; i--)
r[i][C - 1] = r[i - 1][C - 1];
for (int i = C - 1; i > 1; i--)
r[downconditioner][i] = r[downconditioner][i - 1];
r[downconditioner][1] = 0;
}
void dust() {
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
int count = 0;
int spread =r[i][j] / 5;
if (r[i][j] == 0 || r[i][j] == -1)
continue;
for (int k = 0; k < 4; k++) {
int nr = i + rr[k];
int nc = j + cc[k];
if (r[nr][nc] == -1)
continue;
if (nr < 0 || nr >= R || nc < 0 || nc >= C)
continue;
a[nr][nc] += spread;
count++;
}
a[i][j] = a[i][j] - (count * spread);
}
}
for (int i = 0; i < R; i++)
{
for (int j = 0; j < C; j++)
{
r[i][j] += a[i][j];
a[i][j] = 0;
}
}
}
void print()
{
while (T--) {
dust();
conditioner();
}
cout << dust_total << '\n';
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> R >> C >> T;
bool flag = false;
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
cin >> r[i][j];
if (r[i][j] == -1)
{
if (!flag)
{
upconditioner= i;
flag = true;
}
else
downconditioner= i;
}
else {
dust_total += r[i][j];
}
}
}
print();
return 0;
}
문제풀이
main에 코드를 다 작성하고 함수들로 빼주었다. 난 먼저, 행과 열 그리고 반복 타임을 입력받은 후, 공기청정기 위치를 판단하는 과정을 main에서 돌려주었는데, -1일때 위로 돌아가는 upconditioner 하나와 아래로 돌아가는 downcontioner 하나로 구분해서 위치를 저장해주었다. (항상 1번열에만 위치해 있으니, i 값(행)만 저장해주면 됨.) + 전체 먼지(dust_total)또한 값을 저장해주었다.
그런 후, 먼지의 분포 과정을 표현해 주었는데, 0보다 큰값들을 이중for문을 돌리며 찾아내면, 그 먼지를 5로 나눈 값을 rr[]={0,1,0,-1} / cc[]={-1,0,1,0} 과 같이 미리 초기화 시켜준 배열에 해당 배열에 넣어주었다. 대신 여기엔 조건이 붙는데, 값을 넣어주려고 하는 배열이 첫번째이거나 마지막 행과 열일 경우엔 값을 넣어주지 않는다. 이러한 경우에만 count를 해주지 않고, 나머지 경우에만 count를 해준다. count를 해준 값과 5로 나눈 값을 곱하여 기존 먼지량에서 빼준다.
이렇게 먼지에 관한 코드를 짠 후 공기청정기 코드를 짰다. 공기청정기의 위치값을 받아놓은걸 사용하여 배열을 생성 후, 순회하는 식으로 코드를 작성해주면 된다. upconditioner는 위쪽으로, downconditioner는 아래쪽으로 순회하며 해당 배열에 있는 값들을 0으로 초기화 시켜준다.
이 두개의 코드들을 각각의 함수로 분리 시켜 준 후, 반복해주어 최종 먼지양을 출력해주는 함수 또한 생성하여 만들어 준다. 입력받은 T만큼 위 두개의 함수를 실행시켜주면 된다.
그 후, main 함수에서 반복/출력 해주는 함수를 선언해주면 문제를 해결 할 수 있을 것이다.