728x90
2805번: 나무 자르기
첫째 줄에 나무의 수 N과 상근이가 집으로 가져가려고 하는 나무의 길이 M이 주어진다. (1 ≤ N ≤ 1,000,000, 1 ≤ M ≤ 2,000,000,000) 둘째 줄에는 나무의 높이가 주어진다. 나무의 높이의 합은 항상 M보
www.acmicpc.net
- 유형: 이진탐색 (이분탐색)
알고 계시지만 잘 기억 안나는 분들을 위해 이분탐색에 대해 간단히 말하면, 범위에서 중간 값을 해보고, 그에 따라 범위를 수정하고, 이를 반복하는 것이다.
아예 모르시면 검색해보는 것을 추천드립니다...!
- 답안
import sys
# input 값 받기
N, M = map(int, sys.stdin.readline().split())
height = list(map(int, sys.stdin.readline().split()))
# 처음 범위 설정
lo, hi = 0, max(height) # max()를 하면, 범위가 더 좁아질 수 있다는 장점이 있지만, 연산을 한번 더 해야하는 것이므로, max대신 1000,000,000을 사용하는 것도 좋다. (나무의 최대 길이)
# 반복
while lo <= hi:
mid = (lo + hi) // 2 # 중간 값
logsum = 0 # 해당 중간 값으로 했을 때, 나오는 나무의 양을 담기 위한 변수
for i in height: # 각 나무들 체크
if i > mid: # 해당 나무길이 (i)가 자르는 위치보다 커야지만, 나무를 자를 수 있으므로
logsum += i - mid #자른 나무 길이 더해주기
# 범위 재조절
if logsum >= M: # 잘린 나무가 많으면 자르는 위치를 더 높여서 덜 잘라도 되니까
lo = mid+1
else:
hi = mid-1
print(hi)
사실 처음엔 아래처럼 코드를 짰는데, 그러면 if문이 하나 더 들어가서(무한루프) 위에 코드가 훨씬 대중적인 코드인 것 같다.
import sys
N, M = map(int, sys.stdin.readline().split())
height = list(map(int, sys.stdin.readline().split()))
lo, hi = 0, max(height)
while lo < hi:
mid = (lo + hi) // 2
logsum = 0
for i in height:
if i > mid:
logsum += i - mid
if logsum >= M:
if mid==lo:
break
lo = mid
else:
hi = mid
print(lo)
728x90
'알고리즘 및 코딩 > [코딩 연습] 백준,프로그래머스 파이썬 답안 💻' 카테고리의 다른 글
[백준] 14501 퇴사 - 파이썬(dp말고 다른 풀이) (0) | 2023.09.09 |
---|---|
[백준] 1021번 회전하는 큐 (python)파이썬 (0) | 2023.05.12 |
[백준] 1629번: 곱셈 (0) | 2023.05.06 |
[백준] 1012번: 유기농 배추 -python 답안 (파이썬) (0) | 2023.05.06 |
[백준] 10811번: 바구니 뒤집기 - python 풀이 (파이썬) (0) | 2023.05.05 |