B3079-입국심사
날짜 | 2024-04-05 |
사용 언어 | Java |
문제 유형 | |
문제 URL | https://www.acmicpc.net/problem/3079 |
시간 제한 | 메모리 제한 | 제출 | 정답 | 맞힌 사람 | 정답 비율 |
---|---|---|---|---|---|
1 초 | 128 MB | 25557 | 4715 | 3117 | 23.887% |
문제 #
문제 설명 #
제한사항 #
나의 풀이 #
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
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());
// 1 ≤ N ≤ 100,000, 1 ≤ M ≤ 1,000,000,000
int n = Integer.parseInt(st.nextToken());
long m = Long.parseLong(st.nextToken());
// 심사대 시간
ArrayList<Integer> time = new ArrayList<>();
for (int i = 0; i < n; i++) {
time.add(Integer.valueOf(br.readLine()));
}
// time.get(0)가 여러번 쓰이므로 가독성을 위해 역순으로
time.sort(Collections.reverseOrder());
System.out.println(binarySearch(time, n, m));
}
private static int binarySearch(ArrayList<Integer> time, int n, long m) {
// 최소 시간은 0 int start = 0;
// 최대 시간은 10초(두 번째 심사대의 시간) * 6(상근이와 친구들의 수) = 60초
int end = (int) (time.get(0) * m);
while (start <= end) {
// 중간 시간 : (0 + 60) / 2 = 30초.
int mid = (start + end) / 2;
// n개의 심사대에서 mid 시간 동안 소화 가능 한 총 인원 수
int sum = 0;
for (int k = 0; k < n; k++) {
// 시간 내에 k번째 테이블에서 소화 가능 한 사람의 수
sum += mid / time.get(k);
}
// 소화 가능한 인원 수가 친구들 인원 수보다 적으면 시간 내에 모든 사람이 심사를 받을 수 없다.
if (sum < m) {
// 최소 시간을 중간 시간으로 갱식
start = mid + 1;
} else { // 소화 가능한 인원 수가 친구들 인원 수보다 많으면 시간 내에 모든 사람이 심사를 받을 수 있다.
// 최대 시간을 중간 시간으로 갱신
end = mid - 1;
}
}
//
return end+1;
}
}
첫번째 예제 기준
- 최소 시간과 최대 시간 설정:
- 최소 시간은 0
- 최대 시간은 10초(두 번째 심사대의 시간) * 6(상근이와 친구들의 수) = 60초
- 이진 탐색 수행:
- 초기 최소 시간은 0초, 최대 시간은 60초
- 중간 시간 : (0 + 60) / 2 = 30초.
- 30초 동안
- 첫 번째 심사대에서는 30초를 7초로 나눈 몫인 약 4명의 사람을 처리
- 두 번째 심사대에서는 30초를 10초로 나눈 몫인 3명의 사람을 처리
- 따라서 총 7명의 사람을 처리
- 7명은 상근이와 친구들의 수인 6명보다 많음
- 중간 시간인 30초 이하의 시간 내에 모든 사람이 심사를 받을 수 있다.
- 따라서 최대 시간을 중간 시간인 30초로 갱신
- 다시 이진 탐색을 수행하며 최소 시간과 최대 시간을 조정
- 반복 결과 최적의 시간은 28초
다른 사람의 풀이 #