https://www.acmicpc.net/problem/3079
0
초 ~ (maxTime x m)
초 범위에서 mid
초에 대해, 심사 가능한 인원을 계산
=> Init Call: binarySearch(0, maxTime * m)
maxTime x m
: 최장 심사 시간(입력 심사 시간 배열 중, 최대값) x m
명
mid
초 안에 심사 가능한 인원 = (mid / times[i])
의 합
1) mid
초 안에 심사 가능한 총 인원 sum
< 총 인원 m
인 경우
mid
초 안에 모든 인원을 심사하지 못하므로, mid
초를 더 늘려서 다시 탐색start = mid + 1
, end = end
로 다시 탐색2) mid
초 안에 심사 가능한 총 인원 sum
>= 총 인원 m
인 경우
mid
초 안에 모든 인원을 심사하고도 시간이 남으므로, mid
초를 줄여서 다시 탐색minSumTime
갱신start = start
, end = mid - 1
로 다시 탐색long minSumTime
: 출력, 최소 시간
=> 최대값: 10^9 x 10^9 = 10^18 > 21억으로, int
불가능
long mid
: 이진 탐색 범위 0
초 ~ (maxTime x m)
초
=> 최대값: maxTime x m
= 10^18 > 21억으로, int
불가능
long sum
: mid
초 안에 심사 가능한 총 인원
=> 최대값: mid
와 같음 (times[i]
가 모두 1
일 경우)
오답 노트
mid
의 자료형은long
으로 맞게 생각해냈으나,
mid
의 값을 이용하는sum
에 대해서는long
을 생각하지 못함
- 이미
long
으로 선언된 변수long a
를 이용하는 다른 변수b
가 존재하는 경우,- 변수
b
의 자료형도long
을 써야할지 생각해볼 것
mid
)에 대해 for문 n
만큼 반복: O(n log_2 (maxTime x m))import java.io.*;
import java.util.StringTokenizer;
public class Main_Recursive {
static int n, m; // n개 심사대, m명 인원
static int[] times; // 각 심사대의 심사 시간
static int maxTime; // 최대 심사 시간 (times[] 에서 최대값)
static long minSumTime = Long.MAX_VALUE; // 출력, 최소 시간 합
static void binarySearch(long start, long end) {
if (start > end)
return;
long mid = (start + end) / 2;
long sum = 0; // mid 초 안에 심사 가능한 총 인원
for (int i = 0; i < n; i++)
sum += (mid / times[i]);
if (sum < m) {
binarySearch(mid + 1, end);
}
else { // sum >= m
minSumTime = Math.min(minSumTime, mid);
binarySearch(start, mid - 1);
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in)
);
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
times = new int[n];
for (int i = 0; i < n; i++) {
times[i] = Integer.parseInt(br.readLine());
maxTime = Math.max(maxTime, times[i]);
}
// maxTime x m: 최장 심사 시간 x m 명
binarySearch(0, (long) maxTime * m);
System.out.println(minSumTime);
}
}
while
문으로 구현import java.io.*;
import java.util.StringTokenizer;
public class Main_Iterative {
static int n, m; // n개 심사대, m명 인원
static int[] times; // 각 심사대의 심사 시간
static int maxTime; // 최대 심사 시간 (times[] 에서 최대값)
static long minSumTime = Long.MAX_VALUE; // 출력, 최소 시간 합
static void binarySearch(long start, long end) {
while (start <= end) {
long mid = (start + end) / 2;
long sum = 0;
for (int i = 0; i < n; i++)
sum += (mid / times[i]);
if (sum < m) {
start = mid + 1;
}
else {
minSumTime = Math.min(minSumTime, mid);
end = mid - 1;
}
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in)
);
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
times = new int[n];
for (int i = 0; i < n; i++) {
times[i] = Integer.parseInt(br.readLine());
maxTime = Math.max(maxTime, times[i]);
}
binarySearch(0, (long)maxTime * m);
System.out.println(minSumTime);
}
}