Math.min()과 Math.max()의 주의점

이정빈·2024년 5월 11일
0
post-thumbnail

백준 K번째 수 문제

위 문제를 풀다가 사소하지만 주의점 하나를 발견하여 기록해보려한다.

import java.io.*;
import java.util.Scanner;
import java.util.function.DoubleToLongFunction;

public class K번째_수 {
    public static void main(String[] args) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        int N = Integer.parseInt(br.readLine());
        int k = Integer.parseInt(br.readLine());

        long left = 0;
        long right = Math.min(N*N, (long)Math.pow(10,9));
        long mid = 0;
        while(left+1<right){
            mid = (left + right)/2;
            long count = 0;
            for(long i = 1; i<=N; i++){
                count += Math.min(mid / i, N);
            }
            if(count<k){
                left = mid;
            }else right = mid;
        }
        bw.write(right+"");
        bw.flush();

    }
}

위 코드는 논리적으로 맞았지만 오답이었다.

입력을 보면 N은 10^5이하의 값이고, k는 최대 10^9이기 때문에 나는 조심하려고 N과 M을 제외하고는 모두 long으로 선언했다. 어차피 N과 M은 int의 범위 내이기 때문이다.
그런데 왜 틀렸을까?

바로 아래 코드 때문이다.

long right = Math.min(N*N, (long)Math.pow(10,9));

여기서 right를 long으로 선언한 것은 잘했지만 Math.minN*N에서 문제가 발생한다.
N이 int이므로 N*Nint로 인식하는 것이다. 따라서 오버플로우가 발생할 수 있다.

결국 해결하려면 N도 long으로 선언해야하는 것이다.

아래가 정답 코드이다.

import java.io.*;
import java.util.Scanner;
import java.util.function.DoubleToLongFunction;

public class K번째_수 {
    public static void main(String[] args) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        long N = Long.parseLong(br.readLine());
        int k = Integer.parseInt(br.readLine());

        long left = 0;
        long right = Math.min(N*N, (long)Math.pow(10,9));
        long mid = 0;
        while(left+1<right){
            mid = (left + right)/2;
            long count = 0;
            for(long i = 1; i<=N; i++){
                count += Math.min(mid / i, N);
            }
            if(count<k){
                left = mid;
            }else right = mid;
        }
        bw.write(right+"");
        bw.flush();

    }
}

Math.min()Math.max() 안에서 변수를 사용하여 계산하는 값은 그 변수의 자료형을 따름에 주의하자.

profile
사용자의 입장에서 생각하며 문제를 해결하는 백엔드 개발자입니다✍

0개의 댓글

관련 채용 정보