[백준 17144] 미세먼지 안녕! (C#, C++) - soo:bak
작성일 :
문제 링크
설명
격자에 미세먼지와 공기청정기가 있습니다. 매초 미세먼지가 확산되고, 공기청정기가 공기를 순환시킵니다. T초 후 남아있는 미세먼지의 총량을 구하는 문제입니다.
접근법
매초 두 가지 과정이 순서대로 일어납니다. 확산과 공기청정기 작동입니다.
확산은 모든 칸에서 동시에 일어납니다. 각 칸의 미세먼지가 상하좌우로 퍼지는데, 확산되는 양은 해당 칸의 미세먼지를 5로 나눈 값입니다. 공기청정기가 있거나 격자를 벗어나는 방향으로는 확산되지 않습니다. 동시에 일어나므로 원본 배열을 참조하면서 새 배열에 결과를 누적해야 합니다.
공기청정기는 위쪽과 아래쪽 두 칸을 차지합니다. 위쪽에서는 반시계 방향으로, 아래쪽에서는 시계 방향으로 공기가 순환합니다. 순환 경로의 먼지가 한 칸씩 밀리고, 공기청정기로 들어오는 먼지는 정화되어 사라집니다.
이 두 과정을 T번 반복한 후 격자에 남은 미세먼지 양을 모두 더해 출력합니다.
Code
C#
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
using System;
namespace Solution {
class Program {
static int R, C, T;
static int[,] board = new int[51, 51];
static (int r, int c)[] air = new (int, int)[2];
static readonly int[] dr = { -1, 1, 0, 0 };
static readonly int[] dc = { 0, 0, 1, -1 };
static void Diffuse() {
var next = new int[51, 51];
next[air[0].r, air[0].c] = next[air[1].r, air[1].c] = -1;
for (var r = 0; r < R; r++) {
for (var c = 0; c < C; c++) {
if (board[r, c] <= 0)
continue;
var spread = board[r, c] / 5;
var cnt = 0;
for (var d = 0; d < 4; d++) {
var nr = r + dr[d];
var nc = c + dc[d];
if (nr < 0 || nr >= R || nc < 0 || nc >= C)
continue;
if (board[nr, nc] == -1)
continue;
next[nr, nc] += spread;
cnt++;
}
next[r, c] += board[r, c] - spread * cnt;
}
}
board = next;
}
static void Purify() {
var ur = air[0].r;
for (var r = ur - 1; r > 0; r--)
board[r, 0] = board[r - 1, 0];
for (var c = 0; c < C - 1; c++)
board[0, c] = board[0, c + 1];
for (var r = 0; r < ur; r++)
board[r, C - 1] = board[r + 1, C - 1];
for (var c = C - 1; c > 1; c--)
board[ur, c] = board[ur, c - 1];
board[ur, 1] = 0;
var lr = air[1].r;
for (var r = lr + 1; r < R - 1; r++)
board[r, 0] = board[r + 1, 0];
for (var c = 0; c < C - 1; c++)
board[R - 1, c] = board[R - 1, c + 1];
for (var r = R - 1; r > lr; r--)
board[r, C - 1] = board[r - 1, C - 1];
for (var c = C - 1; c > 1; c--)
board[lr, c] = board[lr, c - 1];
board[lr, 1] = 0;
}
static void Main(string[] args) {
var first = Array.ConvertAll(Console.ReadLine()!.Split(), int.Parse);
R = first[0];
C = first[1];
T = first[2];
var airIdx = 0;
for (var r = 0; r < R; r++) {
var line = Array.ConvertAll(Console.ReadLine()!.Split(), int.Parse);
for (var c = 0; c < C; c++) {
board[r, c] = line[c];
if (board[r, c] == -1)
air[airIdx++] = (r, c);
}
}
for (var t = 0; t < T; t++) {
Diffuse();
Purify();
}
var sum = 0;
for (var r = 0; r < R; r++) {
for (var c = 0; c < C; c++) {
if (board[r, c] > 0)
sum += board[r, c];
}
}
Console.WriteLine(sum);
}
}
}
C++
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
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
int R, C, T;
int board[51][51];
pii air[2];
int dr[4] = {-1, 1, 0, 0};
int dc[4] = {0, 0, 1, -1};
void diffuse() {
int next[51][51] = {};
next[air[0].first][air[0].second] = next[air[1].first][air[1].second] = -1;
for (int r = 0; r < R; r++) {
for (int c = 0; c < C; c++) {
if (board[r][c] <= 0)
continue;
int spread = board[r][c] / 5;
int cnt = 0;
for (int d = 0; d < 4; d++) {
int nr = r + dr[d];
int nc = c + dc[d];
if (nr < 0 || nr >= R || nc < 0 || nc >= C)
continue;
if (board[nr][nc] == -1)
continue;
next[nr][nc] += spread;
cnt++;
}
next[r][c] += board[r][c] - spread * cnt;
}
}
memcpy(board, next, sizeof(board));
}
void purify() {
int top = air[0].first;
int bot = air[1].first;
for (int r = top - 1; r > 0; r--)
board[r][0] = board[r - 1][0];
for (int c = 0; c < C - 1; c++)
board[0][c] = board[0][c + 1];
for (int r = 0; r < top; r++)
board[r][C - 1] = board[r + 1][C - 1];
for (int c = C - 1; c > 1; c--)
board[top][c] = board[top][c - 1];
board[top][1] = 0;
for (int r = bot + 1; r < R - 1; r++)
board[r][0] = board[r + 1][0];
for (int c = 0; c < C - 1; c++)
board[R - 1][c] = board[R - 1][c + 1];
for (int r = R - 1; r > bot; r--)
board[r][C - 1] = board[r - 1][C - 1];
for (int c = C - 1; c > 1; c--)
board[bot][c] = board[bot][c - 1];
board[bot][1] = 0;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> R >> C >> T;
int ai = 0;
for (int r = 0; r < R; r++) {
for (int c = 0; c < C; c++) {
cin >> board[r][c];
if (board[r][c] == -1)
air[ai++] = {r, c};
}
}
for (int t = 0; t < T; t++) {
diffuse();
purify();
}
int sum = 0;
for (int r = 0; r < R; r++) {
for (int c = 0; c < C; c++) {
if (board[r][c] > 0)
sum += board[r][c];
}
}
cout << sum << "\n";
return 0;
}