문제링크
https://www.acmicpc.net/problem/16401
문제
명절이 되면, 홍익이 집에는 조카들이 놀러 온다. 떼를 쓰는 조카들을 달래기 위해 홍익이는 막대 과자를 하나씩 나눠준다.
조카들이 과자를 먹는 동안은 떼를 쓰지 않기 때문에, 홍익이는 조카들에게 최대한 긴 과자를 나눠주려고 한다.
그런데 나눠준 과자의 길이가 하나라도 다르면 조카끼리 싸움이 일어난다. 따라서 반드시 모든 조카에게 같은 길이의 막대 과자를 나눠주어야 한다.
M명의 조카가 있고 N개의 과자가 있을 때, 조카 1명에게 줄 수 있는 막대 과자의 최대 길이를 구하라.
단, 막대 과자는 길이와 상관없이 여러 조각으로 나눠질 수 있지만, 과자를 하나로 합칠 수는 없다. 단, 막대 과자의 길이는 양의 정수여야 한다.
입력
첫째 줄에 조카의 수 M (1 ≤ M ≤ 1,000,000), 과자의 수 N (1 ≤ N ≤ 1,000,000)이 주어진다.
둘째 줄에 과자 N개의 길이 L1, L2, ..., LN이 공백으로 구분되어 주어진다. 과자의 길이는 (1 ≤ L1, L2, ..., LN ≤ 1,000,000,000) 를 만족한다.
출력
첫째 줄에 조카 1명에게 줄 수 있는 막대 과자의 최대 길이를 출력한다.
단, 모든 조카에게 같은 길이의 막대과자를 나눠줄 수 없다면, 0을 출력한다.
풀이
import sys
input = sys.stdin.readline
def binary_search(arr, m, left, right):
result = 0
while left <= right:
mid = (left + right) // 2
cnt = sum(lenth // mid for lenth in arr)
if cnt >= m:
result = mid
left = mid + 1
else:
right = mid - 1
return result
m, n = map(int, input().split())
arr = list(map(int, input().split()))
print(binary_search(arr, m, 1, max(arr)))
이진 탐색을 이용하여 풀이했다. left = 1, right = 배열의 가장 큰 값 이며 mid는 나눈 과자의 길이이다. cnt는 나눈 과자의 개수이다. 배열의 원소들을 mid로 나눈 몫의 값을 모두 더해 cnt를 구한 후, cnt가 m(조카 수)보다 같거나 크면 left = mid + 1 한다. 반대로 작다면 right = mid - 1하며, 이를 left가 right보다 작을 때까지만 반복한다. 길이가 길어질 때만 result 값을 갱신하여, 나눠줄 수 있는 가장 긴 과자 길이를 구했다.
'알고리즘(algorithm)' 카테고리의 다른 글
| [백준][Python] 1764 듣보잡 (0) | 2025.05.03 |
|---|---|
| [백준][Python] 14426 접두사 찾기 (0) | 2025.04.12 |
| [백준][Python] 20055 컨베이너 벨트 위의 로봇 (0) | 2025.04.06 |
| [백준][Python] 15724 주지수 - Python (0) | 2025.03.30 |
| [백준][Python] 2659 십자카드 문제 - Python (1) | 2025.03.23 |