K
: 가지고 있는 랜선 길이 (1 ≤ K
≤ 10,000)
N
: 필요한 랜선의 개수 (1 ≤ N
≤ 1,000,000)
→ 항상 K ≦ N
✅ 입력 조건
1.K
,N
공백으로 구분해 입력
2.K
개의 각 랜선의 길이 입력
✅ 출력 조건
1.N
개를 만들 수 있는 랜선의 최대 길이를 센티미터 단위 정수로 출력
입력받은 랜선 길이들을 오름차순 정렬한다.
처음엔 랜선의 길이 중 가장 긴 길이와 가장 짧은 길이를 이용하려 했으나,
랜선의 길이에 비해 N
이 매우 클 경우, 가장 짧은 길이보다 랜선의 최대 길이가 짧을 수 있다는 생각이 들었다.
따라서, 탐색할 범위를 K
의 최소값인 1
부터 최대 길이까지로 잡았다.
가장 긴 랜선과 1의 중간 길이를 구하고,
그 길이를 각 랜선 길이들에 나눠서 몫들의 합을 구한다.
그 합이 원하는 N
과 일치하는지 확인한다.
N
보다 크면 중간 길이에 +1
한 것을 start
로 갱신, N
보다 작으면 중간 길이에 -1
한 것을 end
로 갱신한다.
위의 과정을 start ≤ end
될 때까지 진행하면, end
는 가능한 최대 랜선의 길이가 된다.
이 end
를 출력하면 된다.
위의 조건에 따라 이분탐색을 구현한다.
K개 랜선 리스트 입력받기 →
K개 랜선 오름차순 정렬 →
while문 내 이분 탐색 →
최종 시간복잡도
으로 제한 시간 내에 연산이 가능하다.
리스트의 각 요소들을 나눈 몫의 합이 N이 되도록 이분 탐색하는 방식
import sys
input = sys.stdin.readline
# 1. K, N 입력
K, N = map(int, input().split())
# 2. K번 반복해 길이 입력
lengths = [int(input()) for _ in range(K)]
# 3. 랜선 길이 오름차순 정렬
lengths.sort()
# 4. 이분 탐색 구현
# 4-1. start, end 정의
start = 1
end = lengths[-1]
while start <= end:
# 4-2. mid 정의
mid = (start + end) // 2
# 4-3. 각 길이에 나누어 얻은 몫의 합 계산
count = 0
for length in lengths:
count += length // mid
# 4-4. 조건문에 따라 start, end 조절
if count >= N :
start = mid + 1
else:
end = mid - 1
# 5. 원하는 형식으로 출력
print(end)