MUKER_DEV with iOS

[swift] λ°±μ€€ - 1654번: λžœμ„  자λ₯΄κΈ° λ³Έλ¬Έ

πŸ€– μ•Œκ³ λ¦¬μ¦˜/BAEKJOON

[swift] λ°±μ€€ - 1654번: λžœμ„  자λ₯΄κΈ°

MUKER 2023. 2. 16. 17:02
 

1654번: λžœμ„  자λ₯΄κΈ°

첫째 μ€„μ—λŠ” μ˜€μ˜μ‹μ΄ 이미 가지고 μžˆλŠ” λžœμ„ μ˜ 개수 K, 그리고 ν•„μš”ν•œ λžœμ„ μ˜ 개수 N이 μž…λ ₯λœλ‹€. KλŠ” 1이상 10,000μ΄ν•˜μ˜ μ •μˆ˜μ΄κ³ , N은 1이상 1,000,000μ΄ν•˜μ˜ μ •μˆ˜μ΄λ‹€. 그리고 항상 K ≦ N 이닀. κ·Έ

www.acmicpc.net

문제 ν‘ΈλŠ” 데 μžˆμ–΄ 도움이 λ˜λ„λ‘ λ‚˜μ˜ 풀이와 κ°œμ„ λœ 풀이λ₯Ό μ˜¬λ¦½λ‹ˆλ‹€.
λ˜ν•œ 풀이 ν›„ λ‹€λ₯Έ μ‚¬λžŒμ˜ 풀이λ₯Ό 보고 μ°Έκ³ ν• λ§Œν•œ 풀이도 μ˜¬λ¦½λ‹ˆλ‹€.

- λ¬Έμ œμ— 따라 λ‚˜μ˜ ν’€μ΄λ§Œ μžˆμ„ 수 μžˆμŠ΅λ‹ˆλ‹€.
- ν•΄λ‹Ή 풀이듀은 풀이 쀑 ν•˜λ‚˜μΌ 뿐 μ΅œμ„ μ˜ ν’€μ΄λŠ” 아닐 수 μžˆμŠ΅λ‹ˆλ‹€.

 


 

λ‚˜μ˜ 풀이

let KN = readLine()!.split(separator: " ").map { Int($0)! }
let arr = (0..<KN[0]).map { _ in Int(readLine()!)! }
var left = 1
var right = arr.max()!
while left <= right {
    var count = 0
    let mid = (left + right) / 2
    for i in arr { count += (i / mid) }
    if count < KN[1] { right = mid - 1 }
    else { left = mid + 1 }
}
print(right)

 

- 이진탐색을 μ‚¬μš©ν•΄μ„œ 문제λ₯Ό ν’€ 수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

 

- 이진탐색은 μ •λ ¬λœ λ°°μ—΄μ—μ„œ 탐색할 수 있으며

left, right, mid λ³€μˆ˜λ₯Ό λ§Œλ“€μ–΄ κ΅¬ν˜„ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

λ³€μˆ˜ μ΄λ¦„μ—μ„œ μ•Œ 수 μžˆλ“―μ΄

leftλŠ” λ°°μ—΄μ˜ μ‹œμž‘κ°’(인덱슀)

rightλŠ” λ°°μ—΄μ˜ λ§ˆμ§€λ§‰κ°’(인덱슀)

midλŠ” λ°°μ—΄μ˜ 쀑간값(인덱슀)

κ°€ λ©λ‹ˆλ‹€.

 

- ν•΄λ‹Ή 문제λ₯Ό μ΄μ§„νƒμƒ‰μœΌλ‘œ ν’€μ–΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

μ €ν¬λŠ” N개둜 λ‚˜λˆ μ§ˆ 수 μžˆλŠ” μ΅œλŒ€κΈΈμ΄μ˜ 값을 κ΅¬ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

λ‚˜λˆ„λŠ” λžœμ„ μ˜ κΈΈμ΄λŠ” μ΅œμ†Œ 1cmλΆ€ν„°

주어진 λžœμ„ μ˜ 길이쀑 제일 큰 κ°’κΉŒμ§€ λ“€μ–΄κ°ˆ μˆ˜κ°€ μžˆμŠ΅λ‹ˆλ‹€.

 

- 예제λ₯Ό 예둜 λ“€λ©΄

[802,743,457,539]의 λžœμ„ μ΄ 있고

μ΅œλŒ€ 길이의 λžœμ„ μ„ μ΅œμ†Œ 11개 λ§Œλ“€κ³  μ‹Άμ–΄ ν•©λ‹ˆλ‹€.

 

- μ΅œλŒ€λ‘œ 자λ₯Ό 수 μžˆλŠ” κΈΈμ΄λŠ” λ°°μ—΄μ˜ max값인 802κ°€ λ©λ‹ˆλ‹€.

ν•˜μ§€λ§Œ λ”± 802cm 길이만큼의 ν•˜λ‚˜μ˜ 선밖에 μ–»μ§ˆ λͺ»ν•˜κ² μ£ .

κ·Έλ ‡λ‹€λ©΄ λ„‰λ„‰μž‘μ•„ 1cmλΆ€ν„° 802cm μ•ˆμ—λŠ” 저희가 μ›ν•˜λŠ”

11κ°œκ°€ λ‚˜μ˜€λŠ” μ΅œλŒ€κΈΈμ΄κ°€ μžˆμ„ κ²λ‹ˆλ‹€.

 

- min = 1

max = 802

mid = (min + max) / 2

값이 각각 λ“€μ–΄κ°€κ²Œ λ©λ‹ˆλ‹€.

 

- μ΄μ§„νƒμƒ‰μ˜ 핡심은 min값이 max값을 μ΄ˆκ³Όν•  λ•Œ

저희가 μ›ν•˜λŠ” κ°’μ˜ μœ„μΉ˜λ₯Ό 찾을 수 μžˆμŠ΅λ‹ˆλ‹€.

λ”°λΌμ„œ while문은 min값이 max값을 μ΄ˆκ³Όν•  λ•ŒκΉŒμ§€

계산을 λ°˜λ³΅ν•˜κ²Œ λ©λ‹ˆλ‹€.

 

- whileλ¬Έ μ•ˆμ—μ„œλŠ”

arrλ°°μ—΄ μ•ˆμ— μžˆλŠ” 선을 ν•˜λ‚˜ν•˜λ‚˜ midκ°’λ§ŒνΌ μž˜λΌλ³΄λŠ” κ²λ‹ˆλ‹€.

그리고 옳게 μž˜λΌμ§„ μ„ μ˜ 개수만큼 count에 λ„£μŠ΅λ‹ˆλ‹€.

 

- mid값이 μž‘μ„μˆ˜λ‘ μ΄˜μ΄˜ν•˜κ²Œ 자λ₯΄κ²Œ λ˜λ‹ˆ μ„ μ˜ κ°œμˆ˜λŠ” λ§Žμ•„μ§€κ³ 

mid값이 λ†’μ„μˆ˜λ‘ μ„ μ˜ κ°œμˆ˜λŠ” μ μ–΄μ§‘λ‹ˆλ‹€.

 

- λ§Œμ•½ μ›ν•˜λŠ” 개수만큼 선이 μ•ˆ λ‚˜μ™”λ‹€λ©΄

mid값을 μž‘κ²Œ ν•΄μ•Όκ² μ£ ?

ν˜„μž¬ 802κ°€ λ“€μ–΄μžˆμ„ max값에 (mid-1) 값을 λ„£μ–΄ μ€λ‹ˆλ‹€.

그럼 λ‹€μŒ λ°˜λ³΅μ—μ„œλŠ”

μž‘μ•„μ§„ maxκ°’ 영ν–₯을 λ°›μ•„ midλŠ” μž‘μ•„μ§€κ²Œ λ©λ‹ˆλ‹€.

 

- λ°˜λŒ€λ‘œ μ›ν•˜λŠ” κ°œμˆ˜λ³΄λ‹€ 선이 더 λ‚˜μ™”λ‹€λ©΄

mid값을 크게 ν•˜κΈ° μœ„ν•΄

min값에 (mid+1)을 λ„£μ–΄μ€λ‹ˆλ‹€.

 

- 이런 μ‹μœΌλ‘œ λ°˜λ³΅μ„ 계속해 μ£Όλ‹€ 보면

min값이 max값을 μ΄ˆκ³Όν•˜κ²Œ λ˜λŠ” μˆœκ°„μ΄ μ˜€λŠ”λ°μš”.

while문은 μ’…λ£Œλ˜λ©°

 

- μ΅œμ’…μ μœΌλ‘œ min(left): 201, max(right): 200이 λ“€μ–΄κ°€ μžˆμŠ΅λ‹ˆλ‹€.

λ‘˜μ€ μ„ μ˜ κ°œμˆ˜κ°€ κ΅μ°¨λ˜λŠ” μ§€μ μ—μ„œ λ©ˆμΆ”κ²Œ λ©λ‹ˆλ‹€.

left의 값인 201cmλŠ” 10κ°œκ°€ 잘리고

right의 값인 200cmλŠ” 11κ°œκ°€ μž˜λ¦¬λŠ” μ΅œλŒ“κ°’μ΄ λ©λ‹ˆλ‹€.

 

- 저도 λ³΅μŠ΅ν•  κ²Έ 문제λ₯Ό 풀어썼닀 λ³΄λ‹ˆ

보닀 λͺ…ν™•ν•œ κ°œλ…μ„ μœ„ν•΄μ„œλŠ”

이진탐색과 lower bound , upper boundλ₯Ό κ²€μƒ‰ν•΄μ„œ 곡뢀해 λ³΄μ‹œλŠ” κ±Έ μΆ”μ²œν•©λ‹ˆλ‹€.