읽기 전
- 불필요한 코드나 잘못 작성된 내용에 대한 지적은 언제나 환영합니다.
- 개인적으로 배운 점을 정리한 글입니다.
문제 링크
문제 풀이
단순 탐색이 아니라 이진 탐색의 Upper Bound를 다루는 문제다. 이진 탐색의 조금 고난도 문제는 Bound 문제와 탐색할 수 있는 형태의 문제로 분해하는 과정으로 이루어지는 듯하다. 얻을 수 있는 랜선의 개수를 카운트 하는 함수는 $O(n)$이겠지만 자르는 랜선 간격을 탐색하는 횟수는 이진 탐색을 적용하여 $O(log\ n)$ 내에 발견해야 $O(nlog\ n)$에 해결이 가능하다.
얻을 수 있는 랜선의 최대 길이를 구해야 한다. 여러개라도 1개만 요구하면 갖고 있는 랜선들 중 가장 긴 랜선을 주어야 하므로 최대 시작 간격은 max(보유 랜선 길이)
이고 최소 시작 간격은 역시 1이다.
보유하고 있는 랜선의 개수, 요구 랜선 개수, 랜선 목록을 입력받는다.
랜선 배열들 중 최대값을 추출한다.
얻을 수 있는 랜선 개수를 계산하는 함수를 작성한다. (각 랜선에 대해 탐색 간격으로 나눈 몫이다.)
이진 탐색 알고리즘을 수행한다. (최소 간격이 최대 간격과 동일해질 때까지)
얻고사 하는 전선의 길이가 가능한 최대 길이이므로 최소 간격의 조정이 필요한 경우에 등호를 넣고 버퍼에 현재 탐색 간격을 저장하여 종결 상황을 준비한다.
종료 후 버퍼에 저장된 길이 반환
python 코드
import sys
input = sys.stdin.readline
K, N = map(int, input().split())
arr = []
for _ in range(K):
arr.append(int(input()))
def search(arr, N):
def get_lines(dist):
result = 0
for a in arr:
result += a // dist
return result
min_dist, max_dist = 1, max(arr)
sol = 1
while min_dist <= max_dist:
mid_dist = min_dist + (max_dist - min_dist) // 2
cnt = get_lines(mid_dist)
if cnt >= N:
min_dist = mid_dist + 1
sol = mid_dist
elif cnt < N:
max_dist = mid_dist - 1
return sol
print(search(arr, N))
'Algorithms > Baekjoon' 카테고리의 다른 글
BOJ #1300 K번째 수 (0) | 2021.07.13 |
---|---|
BOJ #2110 공유기 설치 (0) | 2021.07.12 |
BOJ #14500 테트로미노 (0) | 2021.06.19 |
BOJ #14501 퇴사 (0) | 2021.06.19 |
BOJ #7569 토마토 (0) | 2021.06.03 |