[코딩테스트] 💨 미세 먼지 제거 - 백준 17144

2025. 9. 26. 23:41알고리즘

백준 17144

난이도

골드 4

유형

시뮬레이션(구현)

소요시간

2시간 넘게

회고

인덱스 계산을 잘못해서 엄청 오래 걸렸다. ForEach 고집부리지말고, stride를 적극 사용해야겠다.

코드

    let nmt = readLine()!.split(separator: " ").map { Int($0)! }
    let (R, C, T) = (nmt[0], nmt[1], nmt[2])

    var air = [Int]()
    var board = Array(repeating: Array(repeating: 0, count: C), count: R)

    (0..<R).forEach { r in
        let row = readLine()!.split(separator: " ").map { Int($0)! }
        (0..<C).forEach { c in
            board[r][c] = row[c]
            if row[c] == -1 { air.append((r)) }
        }
    }
    let dr = [0, 0, 1, -1]
    let dc = [-1, 1, 0, 0]

    var time = T

    func spread() {
        var distance = Array(repeating: Array(repeating: 0, count: C), count: R)

        (0..<R).forEach { r in
            (0..<C).forEach { c in
                let value = board[r][c] / 5
                var acc = 0
                if value == 0 { return }
                    (0..<4).forEach { k in
                        let nr = r + dr[k]
                        let nc = c + dc[k]

                        if nr < 0 || nr >= R || nc < 0 || nc >= C { return }
                        if board[nr][nc] == -1 { return }

                        acc += 1
                        distance[nr][nc] += value
                    }
                    distance[r][c] -= value * acc
            }
        }

        (0..<R).forEach { r in
            (0..<C).forEach { c in
                board[r][c] += distance[r][c]
            }
        }

        board[air[0]][0] = -1
        board[air[1]][0] = -1
    }

    func purify() {
        let top = air[0]
        let bot = air[1]

        for r in stride(from: top-1, through: 1, by: -1) {
            board[r][0] = board[r-1][0]
        }

        for c in 0..<(C-1) {
            board[0][c] = board[0][c+1]
        }

        for r in 0..<top {
            board[r][C-1] = board[r+1][C-1]
        }

        for c in stride(from: C-1, through: 2, by: -1) {
            board[top][c] = board[top][c-1]
        }

        //

        for r in (bot+1)..<(R-1) {
            board[r][0] = board[r+1][0]
        }

        for c in 0..<(C-1) {
            board[R-1][c] = board[R-1][c+1]
        }

        for r in stride(from: R-1, through: bot+1, by: -1) {
            board[r][C-1] = board[r-1][C-1]
        }

        for c in stride(from: C-1, through: 2, by: -1) {
            board[bot][c] = board[bot][c-1]
        }

        board[top][0] = -1
        board[bot][0] = -1
        board[top][1] = 0
        board[bot][1] = 0
    }

    func printBoard(_ board: [[Int]]) {
        print("----")
        (0..<R).forEach { r in
            (0..<C).forEach { c in
                print(String(format: "%2d", board[r][c]), terminator: " ")
            }
            print()
        }
    }

    while time > 0 {
        time -= 1
        spread()

        purify()
    }
    printBoard(board)

    print(board.flatMap { $0 }.reduce(0, +) + 2)