
막대 과자 n개와 조카 m명이 있다.
과자를 잘라서 조카 한 명당 동일한 길이의 과자 조각을 주되,
한 명당 받는 과자 조각의 최대 길이를 구하는 문제다.
즉,
snack[i]를 길이 mid로 자르면 snack[i] / mid 조각 생성 m명 이상이 되는 최대 mid를 찾는다."한 명당 동일 길이의 최대 조각" → 이진 탐색으로 조각 길이 결정
핵심은 이진 탐색 범위:
중간값 mid로 자를 때:
Σ(snack[i] / mid) start = mid + 1) end = mid - 1)1. 최대 과자 길이 찾기 → 이진 탐색 상한
2. start = 1, end = maxSnack
3. while start <= end:
mid = (start + end) / 2
count = 0
for 각 과자:
count += snack[i] / mid
if count >= m:
answer = mid
start = mid + 1
else:
end = mid - 1
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int m = Integer.parseInt(st.nextToken()); // 조카 수
int n = Integer.parseInt(st.nextToken()); // 과자 수
st = new StringTokenizer(br.readLine());
int[] snack = new int[n];
for (int i = 0; i < n; i++) {
snack[i] = Integer.parseInt(st.nextToken());
}
Arrays.sort(snack);
int startIdx = 1;
int endIdx = snack[n - 1];
int answer = 0;
while (startIdx <= endIdx) {
int mid = (startIdx + endIdx) / 2;
int count = 0;
for (int length : snack) {
count += length / mid;
}
if (count >= m) {
answer = mid;
startIdx = mid + 1;
} else {
endIdx = mid - 1;
}
}
System.out.println(answer);
}
}
입력:
m = 6, n = 6
snack = [19, 10, 12, 32, 26, 48]
정렬 후: [10, 12, 19, 26, 32, 48]
이진 탐색 과정:
mid=24: count = 0+0+0+1+1+2 = 4 < 6 → end=23
mid=12: count = 0+1+1+2+2+4 = 10 ≥ 6 → answer=12, start=13
mid=18: count = 0+0+1+1+1+2 = 5 < 6 → end=17
...
최대 길이 = 15
length / mid 로 조각 수 계산