알고리즘/java

<java> 백준 11834 - 이진탐색

잼추 2024. 6. 10. 01:02

 

https://www.acmicpc.net/problem/11834

 

이 문제는 이진 탐색을 가장한 수학 문제이다.

 

 

일단 배열을 나열해 보면

마지막 숫자들이 속한 그룹(n)의 제곱임을 알 수있다.

 

또한 그룹 내부에서도

자신 그룹의 첫번째 숫자를 1 이라고 할때 2씩 커지기 때문에

이전그룹의 마지막 숫자에서 현재 그룹에서의 index를 구해서

2*index -1을 해주면 문제를 풀 수 있다.

 

해당 풀이를 식으로 구현해 보면 (I는 입력받은 숫자이다.)

답이 2*I -n으로 간단하게 나온다

 

단 I가 10의 100승으로 아주 크기 때문에

모든 숫자는 BigInteger로 처리해 주어야 하고

n을 구할때도 이진 탐색으로 구현하여 시간을 최대한 줄여주어야 한다.

정답

import java.io.*;
import java.math.BigInteger;

public class Q11834 {

    static BigInteger N, n, answer;
    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));

        N = new BigInteger(reader.readLine());
        n = findSmallN(N); // n(n+1)/2 = N 만족하는 n

        answer = N.multiply(BigInteger.TWO).subtract(n);

        writer.write(answer.toString());
        writer.flush();
        writer.close();
    }

    static BigInteger findSmallN(BigInteger target){
        BigInteger start = new BigInteger(String.valueOf(1));
        BigInteger end = new BigInteger("1" + "0".repeat(100));
        while(start.compareTo(end) == -1){
            BigInteger mid = start.add(end.subtract(start).divide(BigInteger.TWO));
            if(calcSum(mid).compareTo(target) == -1){
                start = mid.add(BigInteger.ONE);
            }else{
                end = mid;
            }
        }
        return start;
    }

    static BigInteger calcSum(BigInteger mid){
        return (mid.multiply (mid.add(BigInteger.ONE))).divide(BigInteger.TWO);
    }



}



'알고리즘 > java' 카테고리의 다른 글

<java> 백준 1238 - 다익스트라  (0) 2024.06.14
<java> 이분탐색 사용  (0) 2024.06.08
<java> hashCode  (0) 2024.06.07
<java> stack 대신 deque  (0) 2024.06.06
<java> ArrayDeque vs LinkedList  (1) 2024.06.06