๋ฐฑ์ค - ์นด๋ ์ ๋ ฌํ๊ธฐ(Swift)
2022. 10. 24. 12:48ใAlgorithm
๋ฐฑ์ค - ์นด๋ ์ ๋ ฌํ๊ธฐ(Swift)
๋ฌธ์ ์ค๋ช
https://www.acmicpc.net/problem/1715
๋์ ํ์ด
๊ฐ์ฅ ์์ ์ซ์ 2๊ฐ๋ฅผ ๋ฝ์์ ๋์ ์ํค๋ฉด ๋๋ ๊ฒ์ ์์์ง๋ง 100,000๊ฐ์ธ ์ซ์๋ฅผ sortํ๋ค๋ ๊ฒ์ ์๊ฐ๋ณต์ก๋๊ฐ ๋๋ฌด ๋์์ ธ๋ฒ๋ฆฐ๋ค๋ ํ์ ์ด ์์๋ค.
๊ทธ๋์ ๋ค๋ฅธ์ฌ๋์ ํ์ด๋ฅผ ์ฐธ๊ณ ํ์ฌ ์ฐ์ ์์ ํ๋ฅผ ์ด์ฉํด์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ค.
์๋ ์ฝ๋์ ์ฐ์ ์์ ํ๋ Heap<์๋ฃํ>(array: ๋ฐฐ์ด๋ณ์, sort: ์ ๋ ฌ๋ฐฉํฅ)์ผ๋ก ์ ์ธํ ์ ์์ผ๋ฉฐ remove()!์ insert๋ฅผ ํตํด์ ํ์ logN์ผ๋ก ์ฝ์ , ์ญ์ ๊ฐ ๊ฐ๋ฅํด์ง๋ค.
๊ทธ๋ฆฌ๊ณ ์ด ๋ฌธ์ ๋ n์ด 1์ผ๋๋ ๋น๊ต๋ฅผ ์์ ์ํ๊ธฐ ๋๋ฌธ์ 0์ ์ถ๋ ฅํ๋ ๊ฒ ๋ง๋ค.
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 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 n = Int(readLine()!)!
var numbers: [Int] = []
for _ in 0..<n {
numbers.append(Int(readLine()!)!)
}
var cost = 0
var heap = Heap<Int>(array: numbers, sort: <)
while heap.count > 1 {
let a = heap.remove()!
let b = heap.remove()!
cost += (a+b)
heap.insert(a+b)
}
print(cost)
'Algorithm' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๋ฐฑ์ค A->B(Swift) (0) | 2022.10.24 |
---|---|
๋ฐฑ์ค - ๋ค์ง๊ธฐ(Swift) (0) | 2022.10.24 |
๋ฐฑ์ค - ์ ์ ์ฌ์(Swift) (0) | 2022.10.24 |
๋ฐฑ์ค - 30(Swift) (0) | 2022.10.24 |
๋ฐฑ์ค - ์ฃผ์ ์(Swift) (0) | 2022.10.24 |