2022. 10. 25. 15:30ใAlgorithm
๋ฐฑ์ค - ๋ณด์๋๋(Swift)
๋ฌธ์ ์ค๋ช
https://www.acmicpc.net/problem/1202
๋์ ํ์ด
๊ฐ๊ฒฉ์ ๊ธฐ์ค์ผ๋ก ์ ๋ ฌํ๊ณ ๊ฐ๋ฐฉ์ ๋ฌด๊ฒ๊ฐ ์์ ๊ฒ๋ถํฐ ํ์ํ๋ ์์ด๋์ด๋ ์ฌ๋ฐ๋ฅธ ์ ๊ทผ์ด์์ง๋ง 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 |