728x90
반응형
https://www.acmicpc.net/problem/2512
최종 코드
import sys
def getLimit(left, right, areas, N, M):
answer = min(left, right)
while left <= right:
mid = (left+right)//2
total = 0
for area in areas:
total += min(area, mid)
if total > M:
right = mid-1
else:
answer = mid
left = mid + 1
return answer
input = sys.stdin.readline
N = int(input())
areas = list(map(int, input().split()))
M = int(input())
left = min(min(areas), M//N)
right = max(areas)
print(getLimit(left, right, areas, N, M))
풀이 과정
풀이 시간 47분
문제의 핵심은 국가의 총 예산 M원을 사용하여 N개의 지방의 예산요청을 가능한 최대로 배정해야 한다.
이때, 특정 정수 상한액을 잡아 모든 지방의 예산 요청에 배정해야 한다.
즉, 정수 상한액을 구하기 위한 이분탐색을 진행하면 된다.
import sys
def getLimit(left, right, areas, N, M):
#left와 right 중 작은 값을 answer로 초기화 한다. -> right가 더 작은 경우가 있을 수 있으므로
answer = min(left, right)
#이분 탐색
while left <= right:
#정수 상한액을 mid로 가정
mid = (left+right)//2
#정수 상한액을 mid로 하여 예산요청을 모두 배정할 경우 필요한 총 예산
total = 0
for area in areas:
total += min(area, mid)
#total이 국가 총 예산보다 큰 경우,
if total > M:
#해당 mid 값으로 정수 상한액을 설정할 수 없으므로 right 범위를 줄인다
right = mid-1
#total이 국가 총 예산보다 작거나 같은 경우,
else:
#해당 mid 값으로 정수 상한액을 설정할 수 있다
answer = mid
#이후 가능한 최대의 예산을 사용하는 정수 상한액을 찾기 위해 left 범위를 늘린다
left = mid + 1
return answer
input = sys.stdin.readline
N = int(input())
areas = list(map(int, input().split()))
M = int(input())
#정수 상한액의 최소 범위는 지방의 예산 요청의 최솟값과 국가 예산을 지방의 수로 나눈 값 중 더 작은 값으로 설정한다.
left = min(min(areas), M//N)
#정수 상한액의 최대 범위는 지방의 예산 요청의 최댓값으로 설정한다.
right = max(areas)
print(getLimit(left, right, areas, N, M))
#시간복잡도 = O(log n), 공간복잡도 = O(n)
728x90
반응형
'코테 노트 > 백준' 카테고리의 다른 글
백준 2343 기타 레슨 Python3 (0) | 2022.01.20 |
---|---|
백준 2805 나무 자르기 Python3 (0) | 2022.01.20 |
백준 19236 청소년 상어 C++ (0) | 2021.10.22 |
백준 16236 아기 상어 C++ (0) | 2021.10.20 |
백준 12100 2048(Easy) C++ (0) | 2021.10.17 |