💡 구현/시뮬레이션
Memory 2044KB Time 36ms Code Length 4657B
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
// 미세먼지의 확산. 모든 칸에서 동시에 일어남.!
// - r,c에 있는 미세먼지는 4방향으로 확산됨.
// - 인접방향에 공청기 있거나 칸이 없으면 그방향은 확산 x
// - 확산되는 양은 Ar,c/5이고 소수점은 삭제.
// - r,c에 남은 미세먼지 양은 (원래 있던 미세먼지 - A/5 * 확산된 방향의 갯수)
// 공청기 작동!
// - 공청기에서 바람 나옴
// 위쪽 공청기 바람은 반시계 방향으로 순환. 아래쪽 공청기 바람은 시계방향으로 순환
// 위쪽 공청기 바람은 반시계방향. 아래쪽 공청기 바람은 시계방향 순환
// 미세먼지 맵, 확산 예정 맵 // 공청기 위치, 위치기준으로 돌아야즤~
#include<iostream>
#include<cstring>
using namespace std;
struct info {
int y, x;
};
int R, C, T;
info Robot;
int dust_map[50][50];
int pre_dust_map[50][50];
int result = 0;
void init() {
cin >> R >> C >> T;
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
cin >> dust_map[i][j];
if (dust_map[i][j] == -1) { // 마지막 로봇의 몸통 부분이 저장됨.
Robot.y = i;
Robot.x = j;
}
}
}
}
// 오, 아래, 왼, 위
const int dy[] = { 0, 1, 0 ,-1 };
const int dx[] = { 1, 0, -1 , 0 };
void spread(int y, int x) {
int cnt = 0;
int now_dust = dust_map[y][x];
int will_be_spread_dust = now_dust / 5;
for (int i = 0; i < 4; i++) {
int ny = y + dy[i];
int nx = x + dx[i];
if (ny >= R || nx >= C || ny < 0 || nx < 0) continue;
if (dust_map[ny][nx] == -1) continue; // 공청기 만났을때도 제외
cnt++;
pre_dust_map[ny][nx] += will_be_spread_dust;
}
int after_spread_now_dust = now_dust - will_be_spread_dust * cnt;
pre_dust_map[y][x] += after_spread_now_dust;
}
void make_spread_map() {
memset(pre_dust_map, 0, sizeof(pre_dust_map));
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
if (dust_map[i][j] == -1) continue; // 공청기인 경우 제외
spread(i,j);
}
}
memcpy(dust_map, pre_dust_map, sizeof(dust_map));
// 공청기 위치 재각인
dust_map[Robot.y][Robot.x] = -1;
dust_map[Robot.y-1][Robot.x] = -1;
}
void run_air_conditioner() {
// 위쪽 공기 순환 (반시계므로 시계방향으로 값을 찾아나감)
info now = { 0,0 };
int tmp = dust_map[now.y][now.x];
int dir = 0;
while (1) {
// 다음 위치 저장
int ny = now.y + dy[dir];
int nx = now.x + dx[dir];
if (ny == 0 && nx == 0) { // 다음 위치가 원위치 일 경우
dust_map[now.y][now.x] = tmp; // 저장 해둔 값 복원.
break;
}
if (ny > Robot.y-1 || nx >= C || ny < 0 || nx < 0) { // 범위 초과시 (공청기 위쪽 부근까지만 돌아야함)
dir = (dir + 1) % 4; // 방향 변경
}
else {
if (ny == Robot.y - 1 && nx == Robot.x) { // 다음칸이 공청기 일경우 현재칸에 0넣음
dust_map[now.y][now.x] = 0;
}
else if (ny == Robot.y-2 && nx == Robot.x) { // 다음칸이 공청기 보다 바로 윗칸일경우 현재칸을 -1로 고정하고 넘어감.
dust_map[now.y][now.x] = -1;
}
else {
dust_map[now.y][now.x] = dust_map[ny][nx];
}
now.y = ny;
now.x = nx;
}
}
// 아래 공기 순환 (시계므로 반시계방향으로 값을 찾아나감)
now = { R-1,0 };
tmp = dust_map[now.y][now.x];
dir = 0;
while (1) {
// 다음 위치 저장
int ny = now.y + dy[dir];
int nx = now.x + dx[dir];
if (ny == R-1 && nx == 0) { // 다음 위치가 원위치 일 경우
dust_map[now.y][now.x] = tmp; // 저장 해둔 값 복원.
break;
}
if (ny >= R || nx >= C || ny < Robot.y || nx < 0) { // 범위 초과시 (공청기 아래 부근까지만 돌아야함)
dir = (dir - 1 + 4) % 4; // 방향 변경
}
else {
if (ny == Robot.y && nx == Robot.x) { // 다음칸이 공청기 일경우 현재칸에 0넣음
dust_map[now.y][now.x] = 0;
}
else if (ny == Robot.y+1 && nx == Robot.x) { // 다음칸이 공청기 보다 바로 아랫칸 일경우 현재칸을 -1로 고정하고 넘어감.
dust_map[now.y][now.x] = -1;
}
else {
dust_map[now.y][now.x] = dust_map[ny][nx];
}
now.y = ny;
now.x = nx;
}
}
}
int get_dust_num() {
int dust_num = 0;
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
if (dust_map[i][j] == -1) {
continue;
}
dust_num += dust_map[i][j];
}
}
return dust_num;
}
void print_map() { // debug용
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
printf("%d ", dust_map[i][j]);
}
printf("\n");
}
}
int main() {
init();
while (T--) {
make_spread_map();
run_air_conditioner();
}
result = get_dust_num();
cout << result;
}
이 코드는 미세먼지의 확산과 공기청정기의 작동을 시뮬레이션하는 것이다.
초기에 입력받은 미세먼지 맵에서 미세먼지의 양과 공기청정기의 위치를 저장한다.
확산 함수를 통해 각 칸에서 미세먼지가 4방향으로 확산되며, 인접한 방향에 공기청정기가 있거나 칸이 없는 경우 확산이 일어나지 않는다. 확산되는 양은 해당 칸의 미세먼지 양의 1/5이고, 확산 후 남은 미세먼지 양을 계산하여 저장한다.
공기청정기의 작동 함수를 통해 공기가 반시계방향과 시계방향으로 순환하며, 미세먼지를 이동시킨다. 공기청정기 위쪽과 아래쪽의 동작을 따로 처리한다.
주어진 시간(T)만큼 확산과 공기청정기 작동을 반복하고, 마지막에 전체 미세먼지 양을 계산하여 출력한다.