-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathboj_01202.swift
104 lines (80 loc) · 2.73 KB
/
boj_01202.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
// 2022.04.24
// Dongyoung Kwon @Chuncheonian ([email protected])
// https://www.acmicpc.net/problem/1202
import Foundation
let nk = readLine()!.split{ $0 == " " }.map{ Int(String($0))! }
var jewelryArr = [(Int, Int)]()
var bagArr = [Int]()
var result = 0
for _ in 1...nk[0] {
let n = readLine()!.split{ $0 == " " }.map{ Int(String($0))! }
jewelryArr.append((n[0], n[1]))
}
for _ in 1...nk[1] {
bagArr.append(Int(readLine()!)!)
}
jewelryArr.sort { $0.0 < $1.0 }
bagArr.sort(by: <)
var heap = Heap<Int>(priorityFunction: >)
var index = 0
for bag in bagArr {
while index < jewelryArr.count && jewelryArr[index].0 <= bag {
heap.insert(jewelryArr[index].1)
index += 1
}
if !heap.isEmpty {
result += heap.remove()!
}
}
print(result)
struct Heap<T: Comparable> {
private var elements: [T] = []
private let priorityFunction: (T, T) -> Bool
var isEmpty: Bool { return elements.isEmpty }
var count: Int { return elements.count }
init(elements: [T] = [], priorityFunction: @escaping (T, T) -> Bool) {
self.elements = elements
self.priorityFunction = priorityFunction
}
func leftChildIndex(of index: Int) -> Int {
return 2 * index + 1
}
func rightChildIndex(of index: Int) -> Int {
return 2 * index + 2
}
func parentIndex(of index: Int) -> Int {
return (index - 1) / 2
}
mutating func insert(_ node: T) {
elements.append(node)
swimUp(from: elements.endIndex - 1)
}
mutating func swimUp(from index: Int) {
var index = index
while index > 0, priorityFunction(elements[index], elements[parentIndex(of: index)]) {
elements.swapAt(index, parentIndex(of: index))
index = parentIndex(of: index)
}
}
mutating func remove() -> T? {
if elements.isEmpty { return nil }
elements.swapAt(0, elements.endIndex - 1)
let deleted = elements.removeLast()
diveDown(from: 0)
return deleted
}
mutating func diveDown(from index: Int) {
var higherPriority: Int = index
let leftChildIndex: Int = leftChildIndex(of: index)
let rightChildIndex: Int = rightChildIndex(of: index)
if leftChildIndex < elements.endIndex, priorityFunction(elements[leftChildIndex], elements[higherPriority]) {
higherPriority = leftChildIndex
}
if rightChildIndex < elements.endIndex, priorityFunction(elements[rightChildIndex], elements[higherPriority]) {
higherPriority = rightChildIndex
}
if higherPriority == index { return }
elements.swapAt(higherPriority, index)
diveDown(from: higherPriority)
}
}