728x90
시간 제한 2초, 메모리 제한 128MB
# 조건
- 세준이는 크기가 N×N인 배열 A를 만들었다.
- 배열에 들어있는 수 A[i][j] = i×j 이다.
- 이 수를 일차원 배열 B에 넣으면 B의 크기는 N×N이 된다.
- B를 오름차순 정렬했을 때, B[k]를 구해보자.
- 배열 A와 B의 인덱스는 1부터 시작한다.
입력
- 첫째 줄에 배열의 크기 N이 주어진다.
- N은 10^5보다 작거나 같은 자연수이다.
- 둘째 줄에 k가 주어진다.
- k는 min(10^9, N^2)보다 작거나 같은 자연수이다.
출력
- B[k]를 출력한다.
# 접근 방법
- N의 크기가 100,000까지 가능하므로 모든 좌표의 수를 구하는 것은 메모리 초과가 발생한다.
- 이 문제의 핵심을 잘 생각해봐야 했는데 K번째 인덱스의 수가 무엇인지를 찾아야 한다.
- 즉, k번째 이후의 수는 알 필요가 없다.
- 또한, 배열에 존재하는 규칙을 살펴보면
- 1행 => 1의 곱셈
- 2행 => 2의 곱셈
- 3행 => 3의 곱셈
- 따라서, 임의의 수 t가 존재할 때 1행에는 t // 1개의 t보다 작은 수가 존재하고
- 2행에는 t // 2개 ...
- 여기서 주의해야 할점은 N을 넘어가면 안되므로 min(t//1, N) 같이 비교해주어야 한다.
- 이 때, 임의의 수 t가 존재할 때 배열에 존재하는 t보다 작은 값이 k-1개라면 t가 정답이 되는 것이다.
- 이분 탐색을 활용하여
- left = 0, right = N * N, mid = (left + right) // 2를 해주어 임의의 mid 값을 설정해준다.
- 1~N까지 임의의 수 // i를 하여 개수를 구해준다.
- 여기서 구한 개수가 K보다 작다면 left = mid + 1
- 크다면 right = mid - 1을 해주며 k번째 수를 찾아나가면 된다.
import sys
sys.stdin = open('input.txt')
input = sys.stdin.readline
N = int(input())
K = int(input())
left = 0
right = N*N
while left <= right:
mid = (left + right) // 2
cnt = 0
for i in range(1, N+1):
cnt += min(mid//i, N)
if cnt >= K:
right = mid -1
else:
left = mid + 1
print(left)
728x90
'ALGORITHM > 정렬, 탐색,구현' 카테고리의 다른 글
[백준 22862번] 파이썬 - 가장 긴 짝수 연속한 부분 수열(Large) (0) | 2023.09.07 |
---|---|
[백준 1254번] 파이썬 - 팰린드롬 만들기 (2) | 2023.09.06 |
[백준 17144번] 파이썬 - 미세먼지 안녕! (0) | 2023.09.03 |
[백준 12871번] 파이썬 - 무한 문자열 (0) | 2023.08.31 |
[백준 2900번] 파이썬 - 프로그램 (0) | 2023.08.31 |