코딩하는 해맑은 거북이
[Python] K번째 수 - 백준 (이진탐색) 본문
해당 글은 백준 1300번 'K번째 수' 문제를 다룬다.
문제
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
설명
해당 문제는 2중 for문으로 행렬을 만들고, 인덱스로 접근했을땐 메모리 초과가 떠서 해당 방법으론 풀 수 없었다.
이진탐색으로 nxn 행렬에서 어떤 수보다 작거나 같은 값이 몇 개인지 찾아야 몇 번째 숫자인지 알 수 있다.
예를 들어, 3x3 행렬의 값들을 리스트로 정렬해보면 [1, 2, 2, 3, 3, 4, 6, 6, 9]와 같다.
이때 5보다 작거나 같은 값을 찾아보면, 아래의 수가 존재한다.
1행 : 1x1 ~ 1x3
2행 : 2x1 ~ 2x2
3행 : 3x1
----------- 이는 5를 행으로 나눈 몫과 같다. 이때 나눈 몫의 값이 열의 수를 초과할 수 없으므로 min(값//행, n)이 된다.
1행 : 5//1 -> min(5, n) -> min(5, 3) -> 3개
2행 : 5//2 -> 2개
3행 : 5//3 -> 1개
즉, 5보다 작거나 같은 값은 6개가 된다.
이런식으로 1~nxn의 수에서 이진탐색으로 mid 값보다 작거나 같은 수를 찾아가면 mid가 몇 번째 숫자인지 알 수 있다.
코드
n = int(input())
k = int(input())
start, end = 1, n*n
result = 0
while start <= end:
mid = (start+end)//2
count = 0
for i in range(1, n+1):
count += min(mid//i, n)
if count >= k:
result = mid
end = mid - 1
else:
start = mid + 1
print(result)
'코딩테스트' 카테고리의 다른 글
[Python] 부분합 - 백준 (투 포인터) (0) | 2024.01.07 |
---|---|
[Python] 마인크래프트 - 백준 (2) | 2024.01.06 |
[Python] 예산 - 백준 (이진탐색) (1) | 2024.01.05 |
[Python] 랜선 자르기 - 백준 (이진탐색) (0) | 2024.01.04 |
[Python] 섬의 개수 - 백준 (DFS) (0) | 2024.01.03 |
Comments