

내가 생각했을때 문제에서 원하는부분
첫째 줄에 R, C, T (6 ≤ R, C ≤ 50, 1 ≤ T ≤ 1000) 가 주어진다.
둘째 줄부터 R개의 줄에 Ar,c (-1 ≤ Ar,c ≤ 1,000)가 주어진다.
공기청정기가 설치된 곳은 Ar,c가 -1이고, 나머지 값은 미세먼지의 양이다.
-1은 2번 위아래로 붙어져 있고, 가장 윗 행, 아랫 행과 두 칸이상 떨어져 있다.
첫째 줄에 T초가 지난 후 구사과 방에 남아있는 미세먼지의 양을 출력한다.
내가 이 문제를 보고 생각해본 부분
room 배열: 격자판을 나타내며 미세먼지 양과 공기청정기 위치를 표현한다.
airCleanerUp과 airCleanerDown 변수: 공기청정기 상하 위치 행 번호를 저장한다.
spreadDust() 함수:
새로운 임시 배열 tempRoom에 확산된 미세먼지 양을 저장한다.
각 칸에서 5로 나눈 몫을 확산량으로 계산하고, 가능한 방향으로 확산한다.
확산한 총량만큼 원래 칸에서는 미세먼지가 줄어들고, 확산된 칸에는 미세먼지가 더해진다.
공기청정기 위치는 항상 -1로 고정시킨다.
operateAirCleaner() 함수:
위쪽 공기청정기 바람의 반시계 방향 순환과, 아래쪽 공기청정기 바람의 시계 방향 순환을 구현했다.
바람이 부는 방향으로 미세먼지들이 한 칸씩 밀리며 공기청정기 위치에는 항상 0을 할당하여 미세먼지가 정화된 상태를 나타낸다.
메인에서 T초 동안 두 단계(확산, 청정)를 반복 수행한 후, 남아있는 미세먼지 총합을 계산하여 출력한다.
코드로 구현
package baekjoon.baekjoon_33;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
// 백준 17144번 문제
public class Main1328 {
static int R, C, T;
static int[][] room;
static int airCleanerUp, airCleanerDown; // 공기청정기 위치 (위, 아래 행)
// 상, 하, 좌, 우 이동 좌표
static int[] dr = {-1, 1, 0, 0};
static int[] dc = {0, 0, -1, 1};
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
R = Integer.parseInt(st.nextToken());
C = Integer.parseInt(st.nextToken());
T = Integer.parseInt(st.nextToken());
room = new int[R][C];
airCleanerUp = -1;
airCleanerDown = -1;
// 방 상태 입력 및 공기청정기 위치 찾기
for (int r = 0; r < R; r++) {
st = new StringTokenizer(br.readLine());
for (int c = 0; c < C; c++) {
room[r][c] = Integer.parseInt(st.nextToken());
if (room[r][c] == -1) {
if (airCleanerUp == -1)
airCleanerUp = r;
else
airCleanerDown = r;
}
}
}
// T초 동안 시뮬레이션 진행
for (int t = 0; t < T; t++) {
spreadDust(); // 미세먼지 확산
operateAirCleaner(); // 공기청정기 작동
}
// 남은 미세먼지 합 계산
int totalDust = 0;
for (int r = 0; r < R; r++) {
for (int c = 0; c < C; c++) {
if (room[r][c] > 0) totalDust += room[r][c];
}
}
System.out.println(totalDust);
br.close();
}
// 미세먼지 확산 메서드
static void spreadDust() {
int[][] tempRoom = new int[R][C];
for (int r = 0; r < R; r++) {
for (int c = 0; c < C; c++) {
if (room[r][c] > 0) {
int spreadAmount = room[r][c] / 5;
int spreadCount = 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 && room[nr][nc] != -1) {
tempRoom[nr][nc] += spreadAmount;
spreadCount++;
}
}
tempRoom[r][c] += room[r][c] - spreadAmount * spreadCount;
}
}
}
// 공기청정기 위치 복사
tempRoom[airCleanerUp][0] = -1;
tempRoom[airCleanerDown][0] = -1;
room = tempRoom;
}
// 공기청정기 작동 메서드
static void operateAirCleaner() {
// 위쪽 공기청정기 - 반시계 방향 순환
int up = airCleanerUp;
// 아래 행에서 위쪽으로 -> tmp
for (int r = up - 1; r > 0; r--)
room[r][0] = room[r - 1][0];
// 왼쪽 열에서 오른쪽으로
for (int c = 0; c < C - 1; c++)
room[0][c] = room[0][c + 1];
// 윗 행에서 아래로
for (int r = 0; r < up; r++)
room[r][C - 1] = room[r + 1][C - 1];
// 오른쪽 열에서 왼쪽으로
for (int c = C - 1; c > 1; c--)
room[up][c] = room[up][c - 1];
room[up][1] = 0; // 공기청정기 바로 옆은 먼지가 없음
// 아래쪽 공기청정기 - 시계 방향 순환
int down = airCleanerDown;
// 아래 공기청정기 아래에서 위로
for (int r = down + 1; r < R - 1; r++)
room[r][0] = room[r + 1][0];
// 아랫 행 왼쪽에서 오른쪽으로
for (int c = 0; c < C - 1; c++)
room[R - 1][c] = room[R - 1][c + 1];
// 오른쪽 열 아래에서 위로
for (int r = R - 1; r > down; r--)
room[r][C - 1] = room[r - 1][C - 1];
// 공기청정기 행 오른쪽에서 왼쪽으로
for (int c = C - 1; c > 1; c--)
room[down][c] = room[down][c - 1];
room[down][1] = 0; // 공기청정기 바로 옆은 먼지 없음
}
}
코드와 설명이 부족할수 있습니다. 코드를 보시고 문제가 있거나 코드 개선이 필요한 부분이 있다면 댓글로 말해주시면 감사한 마음으로 참고해 코드를 수정 하겠습니다.