-
[이진탐색] 백준 1300번책/DoIt 알고리즘 코딩테스트 2024. 11. 24. 23:07
문제
세준이는 크기가 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)보다 작거나 같은 자연수이다.- 10^5 이므로, O(N^2)으로 풀이를 할 경우 메모리 초과가 나온다.
- 이진탐색을 이용하여 풀이를 할 생각을 해야한다. (O(logN))
3*3 예시)
- 3 * 3 배열 형성 (N = 3)
- K 값 : 7
[i]/[j] (인덱스) 1 2 3 결과 1 1 2 3 -> 1의 배수 2 2 4 6 -> 2의 배수 3 3 6 9 -> 3의 배수 K값은 7이므로, A배열을 B배열로 옮겼을 때 오름차순으로 정렬되므로
{1,2,2,3,3,4,6,6,9}로 정렬되므로, 결과는 6이된다
K값보다 낮은수들이 앞쪽에 분포하므로, 각 배열의 행에서 K값보다 앞서는 수들의 개수를 찾으면 된다문제풀이
[핵심]
찾는값 > 행들의 합 : start = middle +1;
찾는값 <= 행들의 합 : end = middle -1; (result값 저장 = middle)
----------------------------------------------------------------------------
middle = 1(첫번째 인덱스) + 7(찾는 값) / 2
첫번째 행)
"1의 배수"
- middle(4) / 1 = 4 (한 행의 개수 최대 개수는 3이므로, 4->3)
두번째 행)
"2의 배수"
- k(4) /2 = 2
세번째 행)
"3의 배수"
- k(4) / 3 = 1
[이진탐색]
"찾는 값 (7) > 6 (첫번째행 + 두번째행 + 세번째행)" : start = middle +1;
(진행...)
----------------------------------------------------------------------------슈도코드
N (배열크기) K (찾는 값) start(시작 인덱스 초기화) end (찾는 값) result (선언) while(start <= end){ int middle = (start + end) /2; int sum = 0; for(행의 개수만큼){ count = middle/i; (행에서 K값보다 작아서 포함되는 수의 개수) if (count가 행의 최대개수가 넘으면) count = 행의 최대 개수 sum += count; (행에서 K값보다 작은 수들의 개수) } if( 찾는 값 <= sum){ end = middle - 1; result = middle; }else{ start = middle + 1; } } result값 출력
구현
import java.io.BufferedReader; import java.io.InputStreamReader; public class App { public static void main(String[] args) throws Exception { BufferedReader bf = new BufferedReader(new InputStreamReader(System.in)); int arrSize = Integer.parseInt(bf.readLine()); int findNum = Integer.parseInt(bf.readLine()); int start = 1; int end = findNum; int result = 0; while(start <= end){ int middle = (start + end) / 2; int sum = 0; int count = 0; for (int i = 1; i < arrSize+1; i++){ count = middle/i; if (count > arrSize){ count = arrSize; } sum += count; } if ( findNum <= sum){ end = middle - 1; result = middle; }else{ start = middle + 1; } } System.out.println(result); } }
'책 > DoIt 알고리즘 코딩테스트' 카테고리의 다른 글
[그리디 알고리즘] 백준 1715번 (0) 2024.12.02 [그리디알고리즘] 백준 11047번 (0) 2024.11.27 [이진탐색] 백준 2343번 (0) 2024.11.22 [이진탐색] 백준 1920번 (0) 2024.11.21 [BFS] 백준 1167번 (트리의 지름) (0) 2024.11.20