-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathboj_02696.swift
125 lines (96 loc) · 3.15 KB
/
boj_02696.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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// 2022.04.25
// Dongyoung Kwon @Chuncheonian ([email protected])
// https://www.acmicpc.net/problem/2696
import Foundation
var answer: String = ""
for _ in 1...Int(readLine()!)! {
var arr = [[Int]]()
let n = Int(readLine()!)!
for _ in 1...(n / 10 + 1) {
arr.append(readLine()!.split{ $0 == " " }.map{ Int(String($0))! })
}
var result: String = "\((n + 1) / 2)\n"
var count: Int = 0
var maxHeap = Heap<Int>(priorityFunction: >)
var minHeap = Heap<Int>(priorityFunction: <)
for (idx, elem) in arr.flatMap({ $0 }).enumerated() {
if idx % 2 == 1 {
minHeap.insert(elem)
} else {
maxHeap.insert(elem)
}
if !minHeap.isEmpty, !maxHeap.isEmpty, maxHeap.peek! > minHeap.peek! {
let a = maxHeap.remove()!
let b = minHeap.remove()!
maxHeap.insert(b)
minHeap.insert(a)
}
if (idx + 1) % 2 == 1 {
result += "\(maxHeap.peek!) "
count += 1
if count % 10 == 0 {
result += "\n"
}
}
}
answer += result + "\n"
}
print(answer)
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
}
var peek: T? {
return elements.first
}
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)
}
}