BOJ#1300 K번째 수
* 문제
* 풀이
- N이 10^5일 때, N*N은 10,000,000,000 이므로 시뮬레이션하여 답을 구하는 것은 시간 내에 불가능합니다.
- 문제를 해결하기 위한 아이디어는 다음과 같습니다.
1. 어떤 수 x가 있을 때, x-1 이하의 수의 개수가 K개 미만이고 x 이하의 수의 개수가 K개 이상인 경우
우리가 찾는 K번째 수는 x 이다.
2. 즉, x는 x 이하의 수의 개수가 K개 이상이면서 가장 작은 수이다.
3. 위 조건을 만족하는 x를 이분 탐색을 통해 찾는다.
,
그러면 x까지 수의 개수는 어떻게 찾을 수 있을까요?
- N이 4일 때
1 2 3 4
2 4 6 8
3 6 8 12
4 8 12 16
i번째 행은 i의 배수임을 알 수 있습니다.
즉, 각 행에서 x이하의 수의 개수는 min(x/i, N)
,
추가적으로 고려해야할 점
- N이 최대 10^5 이므로 N*N에서 int 범위를 넘어가게 됩니다.
- K가 10^9 이하이므로 이분 탐색에서 right 범위를 좁힐 수 있습니다.
* 나의 코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws IOException {
// Input
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
int K = Integer.parseInt(br.readLine());
// Solve
// x를 이분 탐색을 통해 찾는다
// x : x까지의 수가 k개 이상인 가장 작은 수
int left = 1;
int right = (int) Math.min((long) N * N, (long) 1000000000);
int mid;
int ans = 0;
while (left <= right) {
mid = (left + right) / 2;
int cnt = getCnt(mid, N);
if (cnt >= K) {
ans = mid;
right = mid - 1;
} else {
left = mid + 1;
}
}
System.out.println(ans);
}
static int getCnt(int x, int N) {
int cnt = 0;
for (int i = 1; i <= N; i++) {
cnt += Math.min(x / i, N);
}
return cnt;
}
}
'Algorithm > 이분 탐색' 카테고리의 다른 글
BOJ#13706 제곱근 (0) | 2017.10.26 |
---|---|
BOJ#2805 나무 자르기 (0) | 2017.05.24 |