-
백준 1300 K번째 수Algorithm/BOJ 2021. 1. 26. 14:53728x90
출처: https://www.acmicpc.net/problem/1300
분류: 이분탐색
접근방식
풀이 자체는 그냥 이진탐색을 이용하면 돼서 그렇게 어렵지 않지만, 이진탐색으로 접근하기가 어려웠던 문제였습니다.
가장 첫 번쨰 접근은 오름차순으로 정렬했을 때 k번째 수라는 건, B[k] 의 원소보다 작거나 같은 수가 k-1개만큼은 있다는 의미가 됩니다.
그럼 B[k]의 원소가 될 어떤 수를 정하고 이 어떤 수보다 작은 수가 k-1개가 있는지 확인하면 됩니다.
문제는 어떤 수보다 작은 수가 몇 개인지 확인하는 방법입니다.
이 방법만 찾으면 이진탐색으로 어떤 수보다 작은 수의 개수가 k보다 작은지 비교해가며 찾아줄 수 있습니다.어떤 수를 m이라고 했을 때 이 m보다 작은 수가 몇 개가 있는지는 어떻게 확인할 수 있을까요?
문제 행렬의 원소는 i*j로 되어있는데요, 각 행은 그 행의 배수로 이루어져 있습니다.
따라서 m을 그 행으로 나눠버리면 그 몫이 m보다 작은 수의 개수가 됩니다.가령 n = 4, m = 7 일 때 2행을 생각해보면
2행은
2 4 6 8 이고
7보다 작은 수는 2, 4, 6 으로 3개가 있고, 7/2 = 3 이 됩니다.말로하니까 복잡한데요. 쉽게 생각해서
7에서 3의 배수가 몇 개인지 생각해보면,
7 = 3 + 3 + 1 이 되니까,
7을 3으로 나눠버린 몫인 2가 7보다 작은 수의 개수가 되는겁니다.실수하면 안 되는 건 n=5, k = 7 일 때 1행은 최대 5개인데 그냥 7/1로 해버리면 7이 되겠죠?
따라서 n과 m/i 중에서 더 작은 수로 생각해줘야 합니다.여기까지 이해하셨다면 나머지는 기본적인 이진탐색으로 풀 수 있습니다 :)
추가로 n이 k보다 크다면 1행만 해도 k보다 작거나 같은 수가 최소한 k개는 있게 됩니다.
작아도 n은 대칭 형태를 이루고 있으므로 k개 보다는 많겠죠?
따라서 high의 초기값을 k로 잡아줘도 될 것 같습니다.해결방법
다른 분들에 비해 제 풀이가 유난히 속도가 느린데..
다른 분들 풀이를 참고해서 범위 등을 조금씩 개선했는데도 별로 차이가 없네요..
이유를 잘 모르겠습니다 :(
protocol Readable { func readSingleValue() -> String func readArray(with separator: Character) -> [String] } extension Readable { func readSingleValue() -> String { return readLine()! } func readSingleValue() -> Int { return Int(readLine()!)! } func readArray(with separator: Character) -> [String] { return readLine()!.split(separator: " ").map { String($0) } } func readArray(with separator: Character) -> [Int] { return readLine()!.split(separator: " ").map { Int(String($0))! } } } class BOJ1300: Readable { func input() { n = readSingleValue() k = readSingleValue() } // MARK: Properties var n: Int! var k: Int! // MARK: Solution func solution() { input() var low = 0 var high = k! while low <= high { let m = (low + high) / 2 var sum = 0 for i in 1...n { sum += min(m / i, n) } if sum >= k { high = m-1 } else { low = m+1 } } print(low) } } BOJ1300().solution()
배운점
어떻게 풀어야하나 감이 안 와서 다른 분들의 풀이를 참고해서 해결했습니다.
이진 탐색 문제인 걸 알고 접근했어도 이해하는 게 쉽지 않았네요...
이것이 사고력인가 봅니다...
그래도 연습으로 기를 수 있다고 믿습니다! 부족한만큼 달려야겠습니다 🔥
'Algorithm > BOJ' 카테고리의 다른 글
백준 2252 줄 세우기 (0) 2021.01.27 백준 13904 과제 (0) 2021.01.27 백준 1339 단어 수학 (0) 2021.01.22 백준 1806 부분합 (0) 2021.01.22 백준 1967 트리의 지름 (0) 2021.01.21