๋ฐฑ์ค€ - ๋ณด์„๋„๋‘‘(Swift)

2022. 10. 25. 15:30ใ†Algorithm

๋ฐฑ์ค€ - ๋ณด์„๋„๋‘‘(Swift)

 

 

 ๋ฌธ์ œ ์„ค๋ช…

 

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

 

1202๋ฒˆ: ๋ณด์„ ๋„๋‘‘

์ฒซ์งธ ์ค„์— N๊ณผ K๊ฐ€ ์ฃผ์–ด์ง„๋‹ค. (1 ≤ N, K ≤ 300,000) ๋‹ค์Œ N๊ฐœ ์ค„์—๋Š” ๊ฐ ๋ณด์„์˜ ์ •๋ณด Mi์™€ Vi๊ฐ€ ์ฃผ์–ด์ง„๋‹ค. (0 ≤ Mi, Vi ≤ 1,000,000) ๋‹ค์Œ K๊ฐœ ์ค„์—๋Š” ๊ฐ€๋ฐฉ์— ๋‹ด์„ ์ˆ˜ ์žˆ๋Š” ์ตœ๋Œ€ ๋ฌด๊ฒŒ Ci๊ฐ€ ์ฃผ์–ด์ง„๋‹ค. (1 ≤ Ci

www.acmicpc.net

 

 

 

 ๋‚˜์˜ ํ’€์ด

 

๊ฐ€๊ฒฉ์„ ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌํ•˜๊ณ  ๊ฐ€๋ฐฉ์˜ ๋ฌด๊ฒŒ๊ฐ€ ์ž‘์€ ๊ฒƒ๋ถ€ํ„ฐ ํƒ์ƒ‰ํ•˜๋Š” ์•„์ด๋””์–ด๋Š” ์˜ฌ๋ฐ”๋ฅธ ์ ‘๊ทผ์ด์˜€์ง€๋งŒ n๊ณผ k๊ฐ€ 300,000๊นŒ์ง€์ด๊ธฐ ๋•Œ๋ฌธ์— 

for๋ฌธ์•ˆ์— filter์—์„œ๋Š” 300,000*(300000log300000)์˜ ์‹œ๊ฐ„๋ณต์žก๋„๋ฅผ ๊ฐ–๊ฒŒ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋งž์ง€์•Š์•˜๋‹ค.

 

 

import Foundation

let n = Int(readLine()!)!
let k = Int(readLine()!)!
var arr: [(Int, Int)] = []
var bags:[Int64] = []
var result = 0
for _ in 0..<n {
    let input = readLine()!.components(separatedBy: " ").map{Int($0)!}
    arr.append((input[0], input[1]))
}
arr.sort(by: {$0.1 == $1.1 ? $0.0 < $1.0 : $0.1 > $1.1 })

for _ in 0..<k {
    bags.append(Int(readLine()!)!)
}
bags.sort(by: <)

for bag in bags {
    let temp = arr.filter{ bag >= $0.0 }
    if temp.count > 0 {
        result += temp[0].1
        arr = arr.filter{ $0 != temp[0] }
    }
}
print(result)

 

๊ทธ๋ž˜์„œ ๋‹ค๋ฅธ์‚ฌ๋žŒ์˜ ํ’€์ด๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ ๋‹ค์‹œ ์ž‘์„ฑํ–ˆ๋‹ค.

 

๋จผ์ € ๋ฌด๊ฒŒ ๋ณ„๋กœ arr๊ณผ bags๋ฅผ ์ •๋ ฌํ•˜๊ณ  bags์˜ ๊ฐ€๋ฐฉ์„ ํƒ์ƒ‰ํ•˜๋ฉด์„œ ์กฐ๊ฑด์— ๋ถ€ํ•ฉํ•˜๋Š” ๊ฒฝ์šฐ์— ํž™์— ๋„ฃ๊ณ  ๋ถ€ํ•ฉํ•˜์ง€ ์•Š๋‹ค๋ฉด while๋ฌธ์„ ํƒˆ์ถœํ•˜๋Š” ์‹์œผ๋กœ ๋‘์—ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ํ•ต์‹ฌ์€ idx๊ฐ€ ์ „์—ญ๋ณ€์ˆ˜๋กœ ๋˜์–ด์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ณ„์† ์ดˆ๊ธฐํ™”๋˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๊ณ  while๋ฌธ์ด ์ „์— ๋Š๊ธด ๋ถ€๋ถ„์—์„œ ๋‹ค์‹œ ์ด์–ด์„œ ๊ฒ€์‚ฌ๋ฅผ ํ•˜๊ฒŒ ๋œ๋‹ค. 

 

๊ฒฐ๊ตญ ์ฒ˜์Œํ–ˆ๋˜ ํ’€์ด๋Š” ๊ฐ€๋ฐฉ๋งˆ๋‹ค ๋ชจ๋“  arr์„ ๋Œ์•„์•ผ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— O(๊ฐ€๋ฐฉ์˜ ๊ฐœ์ˆ˜ * ๋ณด์„์˜ ๊ฐœ์ˆ˜)์˜€๋Š”๋ฐ ์šฐ์„ ์ˆœ์œ„ ํ๋ฅผ ์ด์šฉํ•ด์„œ ํ•œ ํ’€์ด๋Š” 

O(๊ฐ€๋ฐฉ์˜ ๊ฐœ์ˆ˜ + ๋ณด์„์˜ ๊ฐœ์ˆ˜)๊ฐ€ ๋˜๋Š” ๊ฒƒ์ด๋‹ค. 

 

import Foundation

public struct Heap<T> {
    
    private var nodes = [T]()
    
    private var orderCriteria: (T, T) -> Bool
    
    public init(sort: @escaping (T, T) -> Bool) {
        // ์ตœ๋Œ€ ํž™์ธ์ง€ ์ตœ์†Œ ํž™์ธ์ง€ ๊ธฐ์ค€์„ ์žก๋Š”๋‹ค.
        self.orderCriteria = sort
    }
    
    public init(array: [T], sort: @escaping (T, T) -> Bool) {
        self.orderCriteria = sort
        configureHeap(from: array)
    }
    
    public var isEmpty: Bool {
        return count == 0
    }
    
    public var count: Int {
        return nodes.count
    }
    
    public func peek() -> T? {
        return nodes.first
    }
    
    public mutating func insert(_ value: T) {
        nodes.append(value)
        shiftUp(nodes.count - 1)
    }
    
    public mutating func remove() -> T? {
        guard !nodes.isEmpty else { return nil }
        
        if nodes.count == 1 {
            return nodes.removeLast()
        } else {
            let value = nodes[0]
            nodes[0] = nodes.removeLast()
            shiftDown(0)
            return value
        }
    }
    
    public mutating func remove(at index: Int) -> T? {
        guard index < nodes.count else { return nil }
        
        let lastIndex = nodes.count-1
        if index != lastIndex {
            nodes.swapAt(index, lastIndex)
            shiftDown(from: index, until: lastIndex)
            shiftUp(index)
        }
        
        return nodes.removeLast()
    }
    
    // ๋ณ€์ˆ˜๋ฅผ ์ง์ ‘ ๋ณ€๊ฒฝํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— mutating ์„ ์‚ฌ์šฉํ•œ๋‹ค.
    private mutating func configureHeap(from array: [T]) {
        nodes = array
        
        /**
         * ํž™ ํŠธ๋ฆฌ์—์„œ n/2 - 1 ์€ ํ•˜๋‚˜ ์œ„ ์ธต์œ„๊ฐ€ ๋œ๋‹ค.
         * shiftDown์„ ํ•˜๋ฉด์„œ ์ž๋ฆฌ๋ฅผ ์žก์„ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์—
         * ๋งˆ์ง€๋ง‰ leaf ๋…ธ๋“œ๋“ค์€ ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.
         */
        for i in stride(from: nodes.count/2 - 1, through: 0, by: -1) {
            shiftDown(i)
        }
    }
    
    private func parentIndex(ofIndex i: Int) -> Int {
        return (i - 1) / 2
    }
    
    private func leftChildIndex(ofIndex i: Int) -> Int {
        return 2*i + 1
    }
    
    private func rightChildIndex(ofIndex i: Int) -> Int {
        return 2*i + 2
    }
    
    /**
     * shiftUp์€ ์ž์‹ ๊ณผ ๋ถ€๋ชจ๋ฅผ ๋น„๊ตํ•ด ๋ฐ”๊ฟ”์ค€๋‹ค.
     */
    private mutating func shiftUp(_ index: Int) {
        var childIndex = index
        let child = nodes[childIndex] // ์ฒ˜์Œ์— ๋…ธ๋“œ๋ฅผ ์ €์žฅํ•ด๋‘๊ณ  ์ธ๋ฑ์Šค๋ฅผ ๊ตฌํ•œ ํ›„ ๋ฐ”๊ฟ”์ค€๋‹ค.
        var parentIndex = self.parentIndex(ofIndex: index)
        
        while childIndex > 0 && orderCriteria(child, nodes[parentIndex]) {
            nodes[childIndex] = nodes[parentIndex]
            childIndex = parentIndex
            parentIndex = self.parentIndex(ofIndex: childIndex)
        }
        
        nodes[childIndex] = child
    }
    
    /**
     * shiftDown์€ left, right ์ž์‹ ์ค‘ ์ ํ•ฉํ•œ ๋…€์„์ด ์žˆ์œผ๋ฉด ๋ฐ”๊พธ๋ฉด์„œ ๋ฐ”๋‹ฅ๊นŒ์ง€ ๋‚ด๋ ค๊ฐ„๋‹ค.
     */
    private mutating func shiftDown(from index: Int, until endIndex: Int) {
        let leftChildIndex = self.leftChildIndex(ofIndex: index)
        let rightChildIndex = leftChildIndex + 1
        
        var first = index
        if leftChildIndex < endIndex && orderCriteria(nodes[leftChildIndex], nodes[first]) {
            first = leftChildIndex
        }
        if rightChildIndex < endIndex && orderCriteria(nodes[rightChildIndex], nodes[first]) {
            first = rightChildIndex
        }
        if first == index { return }
        
        nodes.swapAt(index, first)
        shiftDown(from: first, until: endIndex)
    }
    
    private mutating func shiftDown(_ index: Int) {
        shiftDown(from: index, until: nodes.count)
    }
    
}
let nk = readLine()!.split(separator: " ").map { Int(String($0))! }
var arr = [(m: Int, v: Int)]()
var bags = [Int]()
var result: Int = 0
for _ in 0..<nk[0] {
    let d = readLine()!.split(separator: " ").map { Int(String($0))! }
    arr.append((d[0], d[1]))
}
for _ in 0..<nk[1] {
    bags.append(Int(readLine()!)!)
}

arr.sort{ $0.m < $1.m }
bags.sort(by: <)

var heap = Heap<(Int, Int)>(array: [], sort: {$0.1 > $1.1})
var idx = 0
for bag in bags {
    while idx < arr.count, arr[idx].0 <= bag {
        heap.insert(arr[idx])
        idx += 1
    }
    let temp = heap.remove()
    result += temp?.1 ?? 0
}
print(result)

 

 

 ํ”ผ๋“œ๋ฐฑ

 

ํ•ญ์ƒ ์‹œ๊ฐ„๋ณต์žก๋„๋ฅผ ๊ณ ๋ คํ•ด์„œ ๋ฌธ์ œ๋ฅผ ํ’€์–ด์•ผํ•œ๋‹ค. ์ด ๋ฌธ์ œ๊ฐ™์€ ๊ฒฝ์šฐ๋Š” ํ‰๋ฒ”ํ•œ filter๋ฅผ ๋Œ๋ฆฌ๊ธฐ์—๋Š” ๋„ˆ๋ฌด ์ปค์„œ ์šฐ์„ ์ˆœ์œ„ ํ๋ฅผ ์ด์šฉํ•ด์•ผํ–ˆ๋‹ค. ์šฐ์„ ์ˆœ์œ„ ํ๋Š” ์‚ฝ์ž…, ์‚ญ์ œ๊ฐ€ logN์ด๊ธฐ ๋•Œ๋ฌธ์— ๋งค์šฐ ์ž‘์€ ์‹œ๊ฐ„๋ณต์žก๋„๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

 

nil์ด ๋  ์ˆ˜ ์žˆ๋Š” ๋ณ€์ˆ˜๊ฐ™์€ ๊ฒฝ์šฐ์—๋Š” ?๋ฅผ ๋ถ™์—ฌ์ค˜์„œ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. 

์œ„์˜ ์˜ˆ์‹œ๋กœ let temp = heap.remove()๊ฐ™์€ ๊ฒฝ์šฐ temp๋Š” ์˜ต์…”๋„์˜ ๊ฐ’์ด ๋˜๊ณ  temp?.1์„ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ temp๊ฐ€ nil์ด ์•„๋‹ˆ๋ผ๋ฉด ์–ธ๋ž˜ํ•‘ํ•ด์„œ ๋‚˜์˜ค๊ณ  nil์ด๋ผ๋ฉด ๊ทธ ๋Œ€์ฒด๊ฐ’์œผ๋กœ 0์„ ๋ฆฌํ„ดํ•˜๋„๋ก ํ–ˆ๋‹ค.

 

'Algorithm' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

๋ฐฑ์ค€ - ์ˆ˜ ๋ฌถ๊ธฐ(Swift)  (0) 2022.10.25
๋ฐฑ์ค€ - ๊ธฐํƒ€์ค„(Swift)  (0) 2022.10.25
๋ฐฑ์ค€ - ์บ ํ•‘(Swift)  (0) 2022.10.25
๋ฐฑ์ค€ A->B(Swift)  (0) 2022.10.24
๋ฐฑ์ค€ - ๋’ค์ง‘๊ธฐ(Swift)  (0) 2022.10.24