17144. 미세먼지 안녕! - node.js / javascript

윤상준·2022년 7월 1일
0

BOJ - node.js / javascript

목록 보기
53/55
post-thumbnail

문제

내 코드

let fs = require("fs");
let input = fs.readFileSync("/dev/stdin").toString().trim().split("\n");

function solution(input) {
    let [R, C, T] = input[0].split(" ").map(Number);
    input = input.slice(1).map((v) => v.split(" ").map(Number));
    let answer = 0;
    let upperCleaner = [0, 0];
    let lowerCleaner = [0, 0];
    let flag = false;
    const dx = [1, 0, -1, 0];
    const dy = [0, 1, 0, -1];

    // 미세먼지 확산
    function spreadDust() {
        let spreadList = [];
        for (let row = 0; row < R; row++) {
            for (let col = 0; col < C; col++) {
                if (input[row][col] > 0) {
                    const value = Math.floor(input[row][col] / 5);
                    for (let i = 0; i < 4; i++) {
                        const [nRow, nCol] = [row + dx[i], col + dy[i]];
                        if (nRow < 0 || nRow >= R || nCol < 0 || nCol >= C || input[nRow][nCol] === -1) continue;
                        spreadList.push([nRow, nCol, value]);
                        input[row][col] -= value;
                    }
                }
            }
        }

        for (let spread of spreadList) {
            const [row, col, value] = spread;
            input[row][col] += value;
        }
    }

    // 위쪽 공기청정기 순환 (반시계방향)
    function rotateUp(cleanerRow) {
        for (let row = cleanerRow - 2; row >= 0; row--) {
            input[row + 1][0] = input[row][0];
        }

        for (let col = 1; col < C; col++) {
            input[0][col - 1] = input[0][col];
        }

        for (let row = 1; row <= cleanerRow; row++) {
            input[row - 1][C - 1] = input[row][C - 1];
        }

        for (let col = C - 2; col > 0; col--) {
            input[cleanerRow][col + 1] = input[cleanerRow][col];
        }

        input[cleanerRow][1] = 0;
    }

    // 아래쪽 공기청정기 순환 (시계방향)
    function rotateDown(cleanerRow) {
        for (let row = cleanerRow + 2; row < R; row++) {
            input[row - 1][0] = input[row][0];
        }

        for (let col = 1; col < C; col++) {
            input[R - 1][col - 1] = input[R - 1][col];
        }

        for (let row = R - 2; row >= cleanerRow; row--) {
            input[row + 1][C - 1] = input[row][C - 1];
        }

        for (let col = C - 2; col > 0; col--) {
            input[cleanerRow][col + 1] = input[cleanerRow][col];
        }

        input[cleanerRow][1] = 0;
    }

    // 남아있는 미세먼지 양 계산
    function countDust() {
        let result = 0;
        for (let row = 0; row < R; row++) {
            for (let col = 0; col < C; col++) {
                if (input[row][col] > 0) result += input[row][col];
            }
        }
        return result;
    }

    // 공기 청정기 위치 찾기
    for (let row = 0; row < R; row++) {
        for (let col = 0; col < C; col++) {
            if (input[row][col] === -1) {
                upperCleaner = row;
                lowerCleaner = row + 1;
                flag = true;
                break;
            }
        }
        if (flag) break;
    }

    // T 만큼 진행 (확산 -> 위쪽 순환 -> 아래쪽 순환)
    while (T--) {
        spreadDust();
        rotateUp(upperCleaner);
        rotateDown(lowerCleaner);
    }

    answer = countDust();
    return answer;
}

console.log(solution(input));

깃허브 링크

https://github.com/highjoon/Algorithm/blob/master/BOJ/17144.js

후기

요구 사항대로 구현하면 되긴 하지만 곳곳에서 킬링 포인트가 느껴졌다.

  1. 미세먼지가 동시에 확산 된다는 점.
  2. 공기 청정기의 위치가 만약 구석에 있다면?

1번 포인트에서 나는 그냥 2중 for문 돌면서 미세먼지 만나면 확산 시키는 방식으로 구현했지만 당연히 오답. 이는 순차적으로 확산시키는 방법이었다.
곰곰이 생각해보다가 확산되는 지점을 모두 모아놓고 한번에 확산시키도록 했다.

2번 포인트는 사실 생각도 못했고 제출하자마자 바로 틀렸다. 그 이후에도 해결법을 찾지 못했고 결국 질문 및 답변을 보고 알았다.

이렇게 2차원 배열을 회전시키는 문제들이 아직 어렵다. 자꾸 놓치는 부분이 생기고 틀리고해서 더 연습이 필요할 것 같다.

profile
하고싶은건 많은데 시간이 없다!

0개의 댓글