포스트

[C++] 백준 17144번: 미세먼지 안녕!

문제

난이도 : 골드 4
백준 17144번 : 미세먼지 안녕!

코드

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 <bits/stdc++.h>

using namespace std;

int R, C, T;
int arr[54][54];
int arr2[54][54];

int dy[] = { -1, 0, 1, 0 };
int dx[] = { 0, 1, 0, -1 };

vector<int> v;

void Spread()
{
    memcpy(arr2, arr, sizeof(arr));

    for (int i = 0; i < R; i++)
    {
        for (int j = 0; j < C; j++)
        {
            if (arr[i][j] < 5) continue;

            int count = 0;

            for (int k = 0; k < 4; k++)
            {
                int ny = i + dy[k];
                int nx = j + dx[k];

                if (ny < 0 || nx < 0 || ny >= R || nx >= C) continue;
                if (arr[ny][nx] == -1) continue;

                arr2[ny][nx] += floor(arr[i][j] / 5);
                count++;
            }

            arr2[i][j] -= (floor(arr[i][j] / 5) * count);
        }
    }

    memcpy(arr, arr2, sizeof(arr));
}

void UpClean()
{
    int prev = 0;
    for (int i = 1; i < C; i++)
    {
        int temp = arr[v[0]][i];
        arr[v[0]][i] = prev;
        prev = temp;
    }

    for (int i = v[0] - 1; i >= 0; i--)
    {
        int temp = arr[i][C - 1];
        arr[i][C - 1] = prev;
        prev = temp;
    }

    for (int i = C - 2; i >= 0; i--)
    {
        int temp = arr[0][i];
        arr[0][i] = prev;
        prev = temp;
    }

    for (int i = 1; i < v[0]; i++)
    {
        int temp = arr[i][0];
        arr[i][0] = prev;
        prev = temp;
    }
}

void DownClean()
{
    int prev = 0;
    for (int i = 1; i < C; i++)
    {
        int temp = arr[v[1]][i];
        arr[v[1]][i] = prev;
        prev = temp;
    }

    for (int i = v[1] + 1; i < R; i++)
    {
        int temp = arr[i][C - 1];
        arr[i][C - 1] = prev;
        prev = temp;
    }

    for (int i = C - 2; i >= 0; i--)
    {
        int temp = arr[R - 1][i];
        arr[R - 1][i] = prev;
        prev = temp;
    }

    for (int i = R - 2; i > v[1]; i--)
    {
        int temp = arr[i][0];
        arr[i][0] = prev;
        prev = temp;
    }
}

int main()
{
    cin >> R >> C >> T;

    for (int i = 0; i < R; i++)
    {
        for (int j = 0; j < C; j++)
        {
            cin >> arr[i][j];
            if (arr[i][j] == -1)
                v.push_back(i);
        }
    }

    while (T--)
    {
        Spread();

        UpClean();
        DownClean();
    }

    int sum = 0;

    for (int i = 0; i < R; i++)
    {
        for (int j = 0; j < C; j++)
        {
            if (arr[i][j] == -1 || arr[i][j] == 0) continue;
            sum += arr[i][j];
        }
    }

    cout << sum;

    return 0;
}

풀이

악으로 깡으로 구현했다. 그래프 문제와 비슷하게 배열 arr에 미세먼지의 수치, 공기청정기의 위치를 입력했다
이때 -1을 입력받을 때 공기청정기의 y좌표를 벡터에 저장했다. 나중에 공기청정기의 바람이 퍼져갈 때 사용할 것임

Spread 함수

미세먼지가 상하좌우로 퍼져나가는 것을 구현한 함수. 배열 두 개를 썼는데 왜냐면 미세먼지가 퍼져나갈 때 퍼져나가기 전 상태에서 봐야 하기 때문이다
(이해 하기 쉬운 예를 들자면 가로로 5 4 0 일 때 5의 상하좌우에 1이 퍼져나가면 4가 5가 되는데 문제에선 이게 퍼져나가면 안된다, 예제를 잘 보면 된다,,,)
그래서 arr 배열의 값을 기준으로 arr2 배열을 만들어서 마지막에 arr2 배열을 arr에 복사한다.
디테일하게 보면 arr의 인덱스가 5보다 작으면 그냥 continue한다. 왜냐면 5보다 작으면 퍼져나갈게 없으니까. 퍼져나간 미세먼지를 count로 해서 퍼뜨린 곳의 미세먼지를 감소시키는 것도 잊지말기

UpClean, DownClean 함수

공기청정기의 작동을 구현한 함수. 솔직히 이렇게 구현하는게 맞나 싶긴한데 어떻게든 구현했다..
Up에서는 공기청정기의 위치를 담은 벡터 v의 0번째 인덱스를 이용하고 Down에서는 1번째 인덱스를 이용한다.
prev를 이용해 다음 배열의 요소에 담으면서 구현했다.


결과

image

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.