https://www.acmicpc.net/problem/1300
1300번: K번째 수
세준이는 크기가 N×N인 배열 A를 만들었다. 배열에 들어있는 수 A[i][j] = i×j 이다. 이 수를 일차원 배열 B에 넣으면 B의 크기는 N×N이 된다. B를 오름차순 정렬했을 때, B[k]를 구해보자. 배열 A와 B
www.acmicpc.net
0. 알고리즘 분류
이분 탐색
1. 문제
2. 풀이
이분탐색 문제이다. 당연하게도, 문제에서 제시하는 순서대로 배열을 만들고 정렬하고 찾으면, 시간초과가 나온다. 필자는 도대체 어떻게 이분탐색을 쓰면 이 문제를 풀 수 있는지 생각해내지 못했다.. 결국 또 구글링이다. 구글링한 결과, 필자로서는 생각조차 못했던, 생각보다도 간단하게 풀리는 문제가 야속했다.
left = 1, right = min(10^9, N*N)로 두고, mid = (left + right)/2 인 mid보다 작은 값의 개수를 세서 k번째 수를 이분탐색으로 찾는다.
right 를 min(10^9, N*N)가 아닌 K로 두는 경우가 많던데, 코드가 간결할 수는 있겠지만 직관적으로 이해하기엔 어렵다고 생각해, 위와 같이 고쳤다. 10^10의 경우엔 overflow가 발생하므로, 최댓값은 10^9이다.
3. 코드
#include <bits/stdc++.h>
using namespace std;
int main() {
int N, K;
scanf("%d %d", &N, &K);
int left = 1, ans;
int right;
if (N < 100*sqrt(100000)) {
right = N*N;
}
else {
right = 10000*100000;
}
while (left <= right) {
long long cnt = 0;
int mid = (left + right) / 2;
for (int i = 1; i <= N; i++)
cnt += std::min(mid / i, N);
if (cnt < K)
left = mid + 1;
else
ans = mid, right = mid - 1;
}
printf("%d", ans);
return 0;
}
'IT > BOJ 문제정리' 카테고리의 다른 글
백준 9521번: LCS (0) | 2021.08.05 |
---|---|
백준 12015번: 가장 긴 증가하는 부분 수열 2 (0) | 2021.08.03 |
백준 2565번: 전깃줄 (0) | 2021.07.28 |
백준 11053번: 가장 긴 증가하는 부분 수열 (0) | 2021.07.28 |
백준 1717번: 집합의 표현 (0) | 2021.07.23 |