[๋ฐฑ์ค] (Swift) 10816๋ฒ - ์ซ์์นด๋2 (์ด๋ถํ์, upper bound, lower bound)
์ด๋ถํ์์ ์งํํ ๋๋ ์กด์ฌ์ฌ๋ถ๋ฅผ ํ์ธํ ๋๋ ๊ด์ฐฎ์ง๋ง, ๊ฐ์๋ฅผ ์ธ์ด์ผํ ๊ฒฝ์ฐ์๋ ํ์ํ๊ณ ์ํ๋ ๋ฐฐ์ด ๋ด๋ถ์ ์ค๋ณต๊ฐ์ด ์์ผ๋ฉด ์๋๋ค. ๊ทธ๋ด๋๋ฅผ ๋๋นํด์ upper bounds ๋ฐฉ๋ฒ๊ณผ lower bounds ๋ฐฉ๋ฒ์ ์ ์์๋์ด์ผ ๋ฌธ์ ๋ฅผ ๋ง์ถ ์ ์์ ๊ฒ ๊ฐ๋ค.
โซ๏ธ ๋ฌธ์
https://www.acmicpc.net/problem/10816
โซ๏ธ ๋์ ํ์ด
์ ๊ทธ๋ฆฌ๊ณ ๋ฌธ์ ํ๊ณ ๋ฐ๊ฒฌํ๊ฑด๋ฐ, dictionary๋ฅผ ์ฌ์ฉํ๋ฉด ์ง์ง ๊ฐ ๊ฐ๋จํ๊ฒ ํ ์ ์๋ค .ใ ใ ใ ใ ใ ใ ใ dictionary์์๋ ๊ฐ์ ์ ๊ทผํ๊ณ , countํด์ฃผ๋ ์๊ฐ๋ณต์ก๋๊ฐ O(1)์ด๊ธฐ ๋๋ฌธ
contain๋ฉ์๋๋ dictionary์์ O(N)์ด๊ธด ํจ
์ฐ์ , ๋ฐฑ์ค์์ ์ด๋ถํ์์ผ๋ก ๋ถ๋ฅ๊ฐ ๋์ด์๋ ๋ฌธ์ ๋ค.
โพ๏ธ ์ฒ์ ์๊ฐํ ํ์ด
๋น์ฐํ ์ฒ์์๋ ์ด๋ถํ์์ผ๋ก ํ์ด์ผ๊ฒ ๋ค๊ณ ์๊ฐํ๋ค.
- ์ ๋ ฅ๋ฐ๋ cards๋ฅผ sort()๋ก ์ ๋ ฌํด์ฃผ๊ณ
- ์ซ์ m๊ฐ๋ฅผ for๋ฌธ์ ๋๋ ค -> O(N)
- ์ด๋ถํ์์ ์งํํ๊ณ , ๋ด๋ถ์ ๊ฐ์ด ์๋ค๋ฉด -> O(logN)
- filter๋ก ์ง๊ธ ๋ณด๊ณ ์๋ ๋ฒ์ ๋ด๋ถ์์ ๊ฐ์ ์ ๋ช๊ฐ์ธ์ง ํ๋จ -> O(N)
์ด๋ ๊ฒ ์๊ฐํ๋ค. ๊ทผ๋ฐ,,,, ์๊ฐํด๋ณด๋๊น, ์ค๊ฐ๊ฐ์ ๊ธฐ์ค์ผ๋ก ๊ณ์ ๋ฒ์๋ฅผ ๋๋๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ filter๋ก start ~ end ๊น์ง ๋ด๋ถ์์ count๋ฅผ ํด์ฃผ๋ฉด ๋์น๋ ์๊ฐ ๋ถ๋ช ํ ์์ ๊ฒ์ด๋ผ๊ณ ์๊ฐ๋์๋ค.
์ด ๊ฒฝ์ฐ์ ๋ง์ฝ ํ๊ฒ์ด 4๋ผ ์น๊ณ , start~end๊น์ง ๋ด๋ถ์์ 4๋ฅผ ์ฐพ์ผ๋ฉด, 2๊ฐ์ด๋ค. ์ฐ๋ฆฌ๊ฐ ์ํ๋ ๋ต์ 3์ด ์๋๊ฐ ? ๊ทธ๋ผ ์ด๋ ๊ฒ filter๋ฅผ ์ด์ฉํ๋ ๋ฐฉ๋ฒ์ ์๋ ๊ฒ ๊ฐ์๋ค.
โพ๏ธ ๋๋ฒ์งธ๋ก ์๊ฐํ ํ์ด
๋๊ฐ์ด ์ด๋ถํ์์ ์งํํ๊ณ , ์ถ๋ ฅ๋ ์์น์ ์์์ ๋์ผํ ๊ฐ์ด ๋ช๊ฐ๊ฐ ์๋์ง ํ๋จํ๋ ๋ฐฉ๋ฒ์ด์๋ค.
- ์ ๋ ฅ๋ฐ๋ cards๋ฅผ sort()๋ก ์ ๋ ฌํด์ฃผ๊ณ
- ์ซ์ m๊ฐ๋ฅผ for๋ฌธ์ ๋๋ ค -> O(N)
- ์ด๋ถํ์์ ์งํํ๊ณ , ๋ด๋ถ์ ๊ฐ์ด ์๋ค๋ฉด ํด๋น mid๊ฐ์ถ๋ ฅ-> O(logN)
- mid ์์ ๊ธฐ์ค์ผ๋ก mid์ ๊ฐ์ ๊ฐ์ ๊ฐ๊ณ ์๋์ง count -> O(N)
์ด๋ ๊ฒ ํ๊ฒ ๋๋ค. ์กฐ๊ฑด์ ์ดํด๋ณด๋ฉด, N์ 50๋ง์ด ์ต๋, M๋ 50๋ง์ด ์ต๋์ธ๋ฐ, ๊ทธ๋ ๊ฒ ๋๋ฉด ์ต์ ์ ๊ฒฝ์ฐ 2์ตํ๊ฐ ๋๋ loop๋ฅผ ๋์์ผํ๋ค. ์๊ฐ์ด๊ณผ๊ฐ ๋๋๊ฒ ๋น์ฐํ์ง ์์๊น?
โพ๏ธ ์ธํฐ๋ท ์ฐธ๊ณ -> upper / lower ๋ฒ์๋ฅผ ๊ตฌํ ์ ์๋ค.
์ธํฐ๋ท์ ๋ณด๋, ์ด๋ถํ์๊ณผ ๋๊ฐ์ ๋ฐฉ์์ผ๋ก ๋์๊ฐ์ง๋ง '๋ฒ์'๋ฅผ ๊ตฌํ๋ ๊ฒ์ ๋ชฉ์ ์ผ๋ก ํจ์๋ฅผ ์์ฑํ ์ ์์๋ค.
- lower bound: ์ํ๋ ๊ฐ k ์ด์์ด ๋์ค๋ ์์น๋ฅผ ์ฐพ์
- upper bound: ์ํ๋ ๊ฐ k ์ด๊ณผ๊ฐ ๋์ค๋ ์์น๋ฅผ ์ฐพ์
์ด๋ ๊ฒ ๋๊ฐ์ ํจ์๋ก ๋๋ ์ ๊ตฌํํ๊ณ , lower bound์ ์ถ๋ ฅ๊ฐ์ ํ๊ฒ๊ฐ ์ด์!์ด ๋์ค๋ ์์น ์ธ๋ฑ์ค๋ฅผ ์ถ๋ ฅํ๊ณ , upper bound๋ ํ๊ฒ๊ฐ ์ด๊ณผ๊ฐ ๋์ค๋ ์๊ฐ์ ์ธ๋ฑ์ค ์์น๋ฅผ ์ฐพ์ ์ถ๋ ฅํ๋ ๊ฒ์ด๋ค.
์ด๋ ๊ฒ ๊ตฌํ๊ฒ ๋๋ฉด, ์ด๋ถํ์์ ๋๋ฒ ์ฌ์ฉํด์ upper๊ฐ๊ณผ lower๊ฐ์ ์ฐพ์๋ด๊ณ (2 * log N), upper - lower ๊ฐ์ ํด์ฃผ๋ฉด ๋ด๊ฐ์ํ๋ ํ๊ฒ๊ฐ์ count ํ์๊ฐ ์ถ๋ ฅ๋๋ค.
โพ๏ธ ํ๋ ธ์ต๋๋ค
์์ฒ๋ผ ํ์๋๋ฐ ํ๋ ธ๋ค. ์ ํ๋ ธ์๊น?
๋ด๊ฐ ๊ตฌํ upper ๊ฐ๊ณผ lower ๊ฐ์ ๋ชจ๋ ์ถ๋ ฅํด์ ์ฐ์ด๋ณด๋ ๋ฌธ์ ๊ฐ ์์๋ค. ๋น์ฅ ๋ฐฑ์ค ์์ ์ ๋์์๋ ์ฌ๋ก๋ก ๋ณด๋ฉด,
ํ๊ฒ๊ฐ์ด ๋ง์ฝ cards ๋ด๋ถ์ ์ต๋๊ฐ์ด๋ผ๋ฉด, cards๋ด๋ถ์์ ์ธ๋ฑ์ค ๊ฐ์ฅ ๋ง์ง๋ง ๊ฐ์ ๊ฐ๋๋ฐ, ๊ทธ๋ผ ์ฐ๋ฆฌ๋ up - low ๊ฐ์ ์ถ๋ ฅํ ๋ ์ํ๋ 3์ด ์๋๋ผ, 2๋ผ๋ ์ถ๋ ฅ๊ฐ์ ๊ฐ๊ฒ ๋๋ค.
๊ทธ๋์ ๋๋, cards๋ฅผ ์ ๋ ฅ๋ฐ๊ณ , ๋งจ ๋ง์ง๋ง ์ ์์๋ก ์ ์ผํฐ์ + 1ํด์ค ๊ฐ(์ฌ๊ธฐ์๋ 11)์ cards์ ์ถ๊ฐ๋ก ๋ฃ์ด์ฃผ์๋ค.
์ ์ ๊น, ๊ทธ๋ผ ๋ target๊ฐ์ด 11์ด ๋๋ค๋ฉด ๋ต์0์ธ๋ฐ 1์ ์ถ๋ ฅํ๊ฒ ๋์ง ์๋๊ตฌ?
์๋๋ค. ์ฐ๋ฆฌ๊ฐ ์ง๊ธ ์ง๋์ ๊ตฌ์กฐ๋ก ๋ณด๋ฉด, ์ด์์ผ ๊ฒฝ์ฐ์ low๋ฅผ ์ค์ ํด์ฃผ๊ณ , ์ด๊ณผ๊ฐ ๋ ๊ฒฝ์ฐ up์ ์ค์ ํด์ฃผ์ง๋ง ์์์ ๋ณด๋ค์ํผ up๊ฐ์ด ์ต๋๊ฐ์ด๋ผ๋ฉด, ๊ทธ๋ฅ cards์ ๋ง์ง๋ง ์ธ๋ฑ์ค๊ฐ์ ๊ฐ๋๋ค.
ํ์ฌ ์์๋ก ๋ฃ์ด์ค 11๋ก ๋ณด๋ฉด, up๊ณผ low๋ ๊ฒฐ๊ตญ ๊ฐ์ ๊ฐ์ ๊ฐ๊ฒ ๋ ๊ฒ์ด๋ค. ๊ทธ๋์ ์ ๋ต์ ๊ฒฐ๊ตญ 0์ด ์ถ๋ ฅ๋๊ฒ ๋๋ค!
โซ๏ธ ์ ๋ต ์ฝ๋
import Foundation
let n = Int(readLine()!)!
var cards = readLine()!.split(separator: " ").map{ Int($0)! }.sorted(by: <)
cards.append(cards[cards.count - 1] + 1)
let m = Int(readLine()!)!
let nums = readLine()!.split(separator: " ").map{ Int($0)! }
func lowerBound(arr: [Int], start: Int, end: Int, target: Int) -> Int {
var start = start
var end = end
while end > start {
let mid = start + ((end - start) / 2)
if arr[mid] >= target {
end = mid
} else {
start = mid + 1
}
}
return start
}
func upperBound(arr: [Int], start: Int, end: Int, target: Int) -> Int {
var start = start
var end = end
while end > start {
let mid = start + ((end - start) / 2)
if arr[mid] > target {
end = mid
} else {
start = mid + 1
}
}
return end
}
for i in 0..<m {
let target = nums[i]
let up = upperBound(arr: cards, start: 0, end: n, target: target)
let low = lowerBound(arr: cards, start: 0, end: n, target: target)
print("\(up - low)", terminator: " ")
}