Swift) 백준 16234번 인구이동 - G4

https://www.acmicpc.net/problem/16234

 

16234번: 인구 이동

N×N크기의 땅이 있고, 땅은 1×1개의 칸으로 나누어져 있다. 각각의 땅에는 나라가 하나씩 존재하며, r행 c열에 있는 나라에는 A[r][c]명이 살고 있다. 인접한 나라 사이에는 국경선이 존재한다. 모

www.acmicpc.net

dfs를 사용해서 그룹으로 묶은 후 그룹의 평균값 구해서 다시 배열에 삽입. 만약 리턴된 그룹의 count 값이 1개보다 커야지만 그룹 배열에 그룹을 추가. for문을 다 돈후 그룹 배열의 count가 0이면은 더이상 인구를 나눌 수 없으므로 break하게 했다.

날짜수 카운트는 인구가 다 이동하고 난 후 카운트가 되도록 하는 것이 문제 조건이므로 이를 유의해야 함.

import Foundation

let nlr = readLine()!.split(separator: " ").map { Int($0)! }
let n = nlr[0]
let l = nlr[1]
let r = nlr[2]

var worldMap: [[Int]] = []
var isGroupMap: [[Bool]] = Array(repeating: Array(repeating: false, count: n), count: n)
var answer = 0

for _ in 0..<n {
    let input = readLine()!.split(separator: " ").map { Int($0)! }
    worldMap.append(input)
}

func makeGroup(i: Int, j: Int, group: [(Int, Int)]) -> [(Int, Int)] {
    if isGroupMap[i][j] {
        return group
    }
    var cpGroup = group
    isGroupMap[i][j] = true
    cpGroup.append((i, j))
    let ni = [0,1,-1,0]
    let nj = [1,0,0,-1]
    for num in 0..<4 {
        let mi = i+ni[num]
        let mj = j+nj[num]
        if mi < 0 || mi >= n || mj < 0 || mj >= n {
            continue
        }
        if isGroupMap[mi][mj] {
            continue
        }
        let countryDiff = abs(worldMap[i][j] - worldMap[mi][mj])
        if countryDiff >= l && countryDiff <= r {
            cpGroup.append(contentsOf: makeGroup(i: mi, j: mj, group: []))
        }
    }
    return cpGroup
}

func calculateWorldMap(groupArr: [(Int, Int)]) {
    var sum = 0
    for num in groupArr {
        sum += worldMap[num.0][num.1]
    }
    let avr = sum / groupArr.count
    for num in groupArr {
        worldMap[num.0][num.1] = avr
    }
}

func initalIsGroupMap() {
    isGroupMap = Array(repeating: Array(repeating: false, count: n), count: n)
}

while true {
    var groupArr: [[(Int, Int)]] = []
    for i in 0..<n {
        for j in 0..<n {
            if isGroupMap[i][j] {
                continue
            }
            let group = makeGroup(i: i, j: j, group: [])
            if group.count > 1 {
                groupArr.append(group)
            }
        }
    }
    groupArr.forEach { arr in
        calculateWorldMap(groupArr: arr)
    }
    if groupArr.count == 0 {
        break
    }
    initalIsGroupMap()
    answer += 1
}

print(answer)