📌 문제
집에서 시간을 보내던 오영식은 박성원의 부름을 받고 급히 달려왔다. 박성원이 캠프 때 쓸 N개의 랜선을 만들어야 하는데 너무 바빠서 영식이에게 도움을 청했다.
이미 오영식은 자체적으로 K개의 랜선을 가지고 있다. 그러나 K개의 랜선은 길이가 제각각이다. 박성원은 랜선을 모두 N개의 같은 길이의 랜선으로 만들고 싶었기 때문에 K개의 랜선을 잘라서 만들어야 한다. 예를 들어 300cm 짜리 랜선에서 140cm 짜리 랜선을 두 개 잘라내면 20cm는 버려야 한다. (이미 자른 랜선은 붙일 수 없다.)
편의를 위해 랜선을 자르거나 만들 때 손실되는 길이는 없다고 가정하며, 기존의 K개의 랜선으로 N개의 랜선을 만들 수 없는 경우는 없다고 가정하자. 그리고 자를 때는 항상 센티미터 단위로 정수길이만큼 자른다고 가정하자. N개보다 많이 만드는 것도 N개를 만드는 것에 포함된다. 이때 만들 수 있는 최대 랜선의 길이를 구하는 프로그램을 작성하시오.
📌 입력
첫째 줄에는 오영식이 이미 가지고 있는 랜선의 개수 K, 그리고 필요한 랜선의 개수 N이 입력된다. K는 1이상 10,000이하의 정수이고, N은 1이상 1,000,000이하의 정수이다. 그리고 항상 K ≦ N 이다. 그 후 K줄에 걸쳐 이미 가지고 있는 각 랜선의 길이가 센티미터 단위의 정수로 입력된다. 랜선의 길이는 231-1보다 작거나 같은 자연수이다.
📌 출력
첫째 줄에 N개를 만들 수 있는 랜선의 최대 길이를 센티미터 단위의 정수로 출력한다.
📌 문제 풀이
👨🏫 접근
일정한 길이로 리스트를 탐색하면서 원하는 값을 찾아야 한다. 값 하나를 탐색해서 원하는 조건을 만족시켜야 하므로 이진 탐색을 통해서 구하도록 한다.
👨🏫 문제 풀이
📄 전체 코드
import sys
n, k = map(int, sys.stdin.readline().split())
lans = list(map(int, sys.stdin.readlines()))
pl, pr = 1, max(lans)
ans = 0
while pl <= pr:
mid = (pl + pr) // 2
tmp = 0
for lan in lans:
tmp += lan // mid
if tmp < k:
pr = mid - 1
else:
pl = mid + 1
ans = mid
print(ans)
📄 준비
import sys
n, k = map(int, sys.stdin.readline().split())
lans = list(map(int, sys.stdin.readlines()))
pl, pr = 1, max(lans)
ans = 0
여기서 큰 실수를 한 게 있는데, 나중에 while 반복문에서 각 랜선에 대하여 몫 연산을 할 예정인데 ZeroDivisionError를 간과하고 있었다. pl이 0이고 pr이 1이면 mid 값을 구할 때 mid가 0이 되어버리고 결국 0으로 값을 나누는 에러를 만들어낸다. 이 부분은 항상 경각심을 가지고 있어야겠다.
📄 풀이
while pl <= pr:
mid = (pl + pr) // 2
tmp = 0
for lan in lans:
tmp += lan // mid
if tmp < k:
pr = mid - 1
else:
pl = mid + 1
ans = mid
print(ans)
이제 본격적으로 이진 탐색을 시작한다. 이번에는 랜선을 일정한 길이로 여러 개 자르는 것이기 때문에 합계를 구할 때 몫 연산자를 사용한다. 그렇기 때문에 pl의 값을 1부터 시작한 것이다.
그렇게 해서 모든 랜선을 잘라서 저장한다. 구할 수 있는 랜선의 개수가 k를 충족하지 못하면 더 짧은 길이로 여러 개 잘라야 하기 때문에 pr을 mid보다 1 작게 저장한다. 반대의 경우도 비슷하게 구한다. 이때, k를 충족하는 경우에는 ans의 값을 매번 최대화 해야 한다. 그렇기 때문에 tmp < k
가 아닐 때에 ans 값을 저장해준다. 길이를 구하는 문제라서 mid 값을 저장했다.
📌 총평
ZeroDivisionError 항상 조심하자,,
'Algorithm > Binary Search' 카테고리의 다른 글
[Python - Binary Search] 3079 입국심사 (0) | 2022.09.13 |
---|---|
[Python - Binary Search, BFS] 2585 경비행기 (2) | 2022.09.13 |
[Python - Binary Search] 2110 공유기 설치 (0) | 2022.09.04 |
[Python - Binary Search] 2512 예산 (0) | 2022.09.04 |
[Python - Binary Search] 2805 나무 자르기 (0) | 2022.09.04 |