문제 : https://www.acmicpc.net/problem/17144
[ 알고리즘풀이 ]
1. 미세먼지 확산
map[x][y] : 현재 (x, y) 지점에 있는 먼지의 양.
dustmap[x][y] : (x,y) 지점에 미세먼지 확산으로 인해 추가될 먼지의 양.
map을 순회하며, 미세먼지가 있다면 주변의 dustmap에 추가될 미세 먼지의 양을 더해줍니다.
순회가 끝났다면, 다시 순회하며 map에 dustmap을 더해주고, dustmap을 0으로 초기화해줍니다.
dustmap을 따로 선언하지않는다면, map에 새롭게 추가되는 먼지와 이미 있던 먼지를 구분할 수 없으므로 map, dustmap 2개의 배열을 이용하면 됩니다.
2. 공기청정기 작동
기존에 공기 청적이의 위치를 따로 저장해 두고, 공기청정기 상단, 하단을 각각 작동시켜 한 칸씩 배열을 shift 하면 됩니다.
#include<iostream>
#include<queue>
using namespace std;
int R, C, T, dustmap[50][50] = {}, map[50][50] = {}, dx[4] = { -1, 0, 1, 0 }, dy[4] = { 0, -1, 0, 1 };
int firstR, secondR;
int curDust(void) {
int sum = 0;
for (int i = 0; i < R; i++)
for (int j = 0; j < C; j++)
if (map[i][j] != -1)
sum += map[i][j];
return sum;
}
void spreadDust(void) {
for(int i = 0; i < R; i++)
for (int j = 0; j < C; j++) {
if (map[i][j] != -1 && map[i][j] != 0) {
int dust = map[i][j] / 5;
for (int k = 0; k < 4; k++) {
int nextX = i + dx[k], nextY = j + dy[k];
if (nextX < 0 || R <= nextX || nextY < 0 || C <= nextY)
continue;
if (map[nextX][nextY] == -1)
continue;
dustmap[nextX][nextY] += dust;
map[i][j] -= dust;
}
}
}
for (int i = 0; i < R; i++)
for (int j = 0; j < C; j++){
if (map[i][j] != -1)
map[i][j] += dustmap[i][j];
dustmap[i][j] = 0;
}
return;
}
void clearAir(void) {
// 위쪽순환
for (int i = firstR - 1; i > 0; i--)
map[i][0] = map[i - 1][0];
for (int j = 0; j < C - 1; j++)
map[0][j] = map[0][j + 1];
for (int i = 0; i < firstR; i++)
map[i][C - 1] = map[i + 1][C - 1];
for (int j = C - 1; j > 1; j--)
map[firstR][j] = map[firstR][j - 1];
map[firstR][1] = 0;
// 아래쪽순환
for (int i = secondR + 1; i < R - 1; i++)
map[i][0] = map[i + 1][0];
for (int j = 0; j < C - 1; j++)
map[R - 1][j] = map[R - 1][j + 1];
for (int i = R - 1; i > secondR; i--)
map[i][C - 1] = map[i - 1][C - 1];
for (int j = C - 1; j > 1; j--)
map[secondR][j] = map[secondR][j - 1];
map[secondR][1] = 0;
}
int main(void) {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> R >> C >> T;
for (int i = 0; i < R; i++)
for (int j = 0; j < C; j++){
cin >> map[i][j];
}
// 공기청정기 위치 확인
for (int i = 0; i < R; i++)
for(int j = 0; j < C; j++)
if (map[i][j] == -1) {
firstR = i, secondR = i + 1;
i = R, j = C;
}
while (T--) {
spreadDust();
clearAir();
}
cout << curDust();
return 0;
}