티스토리 뷰

PS

[Swift] 백준_컬러볼(10800)

희철 2023. 4. 2. 18:07

문제

 

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

 

10800번: 컬러볼

첫 줄에는 공의 개수를 나타내는 자연수 N이 주어진다(1 ≤ N ≤ 200,000). 다음 N개의 줄 중 i번째 줄에는 i번째 공의 색을 나타내는 자연수 Ci와 그 크기를 나타내는 자연수 Si가 주어진다(1 ≤ Ci ≤ N

www.acmicpc.net

 

풀이

 

우선, 공을 크기가 작은 순으로 정렬해줌. 만약 크기가 같은 경우엔 색이 작은 순으로 정렬하였음.

 

cur이라는 변수에 지금까지 나온 공의 사이즈를 전부 더해주었음.

또한, 사이즈별로 몇 개의 공이 있었는지와 색 별로 공 사이즈 합이 얼마인지를 딕셔너리에 계속해서 저장해주었음.

 

i번째 공이 나왔을 때, 딕셔너리에서 nil값이 나오면 나중에 런타임에러가 뜰 것이기때문에 가장 먼저 딕셔너리에 값을 추가해주었음. 이후, 만약 i가 0이 아닐 때 i번째 공과 i - 1번째 공의 정보가 모두 같으면 그냥 result에 이전값과 동일한 값을 넣어주었음.

 

공의 정보가 같지 않다면, temp라는 변수에 cur을 담고 여기서 i번째 공과 같은 사이즈의 공 사이즈합과 같은 색의 공 사이즈 합을 빼주었음. 이때, 딕셔너리에 우선으로 값을 넣었으므로 i번째 값도 포함하고 있는 상태일거임. 그래서 sizeDic같은 경우엔 개수에서 1을 빼주었고, colorDic같은 경우엔 값에서 i번째 공 사이즈를 빼주었음. 

 

마지막으로 temp의 값을 result에 넣어주었음. 공을 처음에 정렬하므로 공의 순서를 기억하고 있어야했기때문에 balls에 값을 추가할 때 i값을 같이 추가하여 이 값을 기준으로 result에 값을 넣어주었음.

import Foundation

final class FileIO {
    private var buffer:[UInt8]
    private var index: Int
    
    init(fileHandle: FileHandle = FileHandle.standardInput) {
        buffer = Array(fileHandle.readDataToEndOfFile())+[UInt8(0)]
        index = 0
    }
    
    @inline(__always) private func read() -> UInt8 {
        defer { index += 1 }
        
        return buffer.withUnsafeBufferPointer { $0[index] }
    }
    
    @inline(__always) func readInt() -> Int {
        var sum = 0
        var now = read()
        var isPositive = true
        
        while now == 10
                || now == 32 { now = read() }
        if now == 45{ isPositive.toggle(); now = read() }
        while now >= 48, now <= 57 {
            sum = sum * 10 + Int(now-48)
            now = read()
        }
        
        return sum * (isPositive ? 1:-1)
    }
    
    @inline(__always) func readString() -> String {
        var str = ""
        var now = read()
        
        while now == 10
                || now == 32 { now = read() } // 공백과 줄바꿈 무시
        
        while now != 10
                && now != 32 && now != 0 {
            str += String(bytes: [now], encoding: .ascii)!
            now = read()
        }
        
        return str
    }
}

let file = FileIO()

let n = file.readInt()
var balls: [(Int,Int,Int)] = []
for i in 0..<n {
    balls.append((file.readInt(), file.readInt(),i))
}
balls.sort {
    if $0.1 == $1.1 {
        return $0.0 < $1.0
    }
    return $0.1 < $1.1
}
var sizeDic: [Int: Int] = [:]
var colorDic: [Int:Int] = [:]
var cur = 0
var result = Array(repeating: 0, count: n)
for i in 0..<balls.count {
    var temp = cur
    if sizeDic[balls[i].1] == nil {
        sizeDic[balls[i].1] = 1
    } else {
        sizeDic[balls[i].1]! += 1
    }
    if colorDic[balls[i].0] == nil {
        colorDic[balls[i].0] = balls[i].1
    } else {
        colorDic[balls[i].0]! += balls[i].1
    }
    if i != 0 && balls[i].0 == balls[i - 1].0 && balls[i].1 == balls[i - 1].1 {
        result[balls[i].2] = result[balls[i - 1].2]
        cur += balls[i].1
        continue
    }
    temp -= (sizeDic[balls[i].1]! - 1) * balls[i].1
    temp -= colorDic[balls[i].0]! - balls[i].1
    result[balls[i].2] = temp
    cur += balls[i].1
}
for i in 0..<result.count {
    print(result[i])
}

 

댓글
최근에 올라온 글
Total
Today
Yesterday