N이 최대 10^5 이므로 아래와같이 구해서는 TLE나 메모리 초과가 난다.
import java.util.Arrays; import java.util.Scanner; public class Sol1300 { //N이 100000이므로 TLE나 메모리 초과남 public static void main(String[] args) { Scanner sc = new Scanner(System.in); int N = sc.nextInt(); //배열의 크기 int K = sc.nextInt(); //k번째 int[][] A = new int[N+1][N+1]; int[] B = new int[(N*N)+1]; int m = 0; for(int i = 1; i <= N; i++){ for(int j = 1; j <= N; j++){ B[m++] = A[i][j] = i*j; } } Arrays.sort(B); System.out.println(B[K]); } } /* 입력 3 7 출력 6 */ |
그래서 이분탐색을 이용해보자!
문제에서 A[i][j] = i*j 라고 했으므로 A배열의 i행의 숫자들은 모두 i의 배수임. 이런 j값들의 갯수를 구하면 되고 곧 j 는 A[i][j]/i 임. A[i][j]값을 이분탐색으로 mid값으로 놓고 돌리면 된다.
그리고 N 이 1000일때는 mid값이 1000*1000/2로 50만으로 N값 10^5을 넘어갈 수 있으므로
Math.min(mid/i, N) 으로 처리 해준다.
import java.util.Arrays; import java.util.Scanner; public class Sol1300_2 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int N = sc.nextInt(); //배열의 크기 int K = sc.nextInt(); //k번째 int left = 1; int right = K; int answer = 0; while(left <= right){ long cnt = 0; int mid = (left + right) / 2; for(int i = 1; i <= N; i++){ //N이 1000일땐 50만/i가 N넘어갈 수 있으므로 min(mid/i, N)처리 cnt += Math.min(mid/i, N); } if(cnt < K){ left = mid + 1; } else{ answer = mid; right = mid - 1; } } System.out.println(answer); } } /* 입력 3 7 출력 6 */ |
'Algorithm' 카테고리의 다른 글
숫자에서 n번째 자리 숫자 추출 (3) | 2015.04.13 |
---|---|
문자열 입력받아 포함된 알파벳 갯수 확인 (0) | 2015.04.11 |
n*n배열을 숫자로 대각선으로 위아래 이동하며 채우기 (0) | 2015.04.09 |
n*n배열을 숫자로 위아래로 반복하며 S자 모양으로 채우기 (0) | 2015.04.09 |
재귀를 이용한 팩토리얼 (0) | 2015.04.08 |
댓글