백준 미세먼지 안녕!

KIMYEONGJUN·2026년 3월 16일
post-thumbnail

문제

내가 생각했을때 문제에서 원하는부분

첫째 줄에 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; // 공기청정기 바로 옆은 먼지 없음
    }
}

마무리

코드와 설명이 부족할수 있습니다. 코드를 보시고 문제가 있거나 코드 개선이 필요한 부분이 있다면 댓글로 말해주시면 감사한 마음으로 참고해 코드를 수정 하겠습니다.

profile
Junior backend developer

0개의 댓글