Study/Problem Solving

[BOJ_3151] 합이 0

monitor 2023. 11. 14. 09:57

설명


어떻게 접근할지는 대강 파악했으나 상세히 떠오르지 않아 블로그를 보고 푼 문제이다.

 

해당 코드는 2개의 지점을 먼저 잡아두고 10000*10000 이분 탐색으로 가능한 범위 내의 숫자들을 가져오는 코드이다.

 

이게 무슨 말이냐면

 

-1,-1,-1,-1,1,2,2,2,2,2,2,3 이런식으로 수열이 들어오면 만일 한 번 이분 탐색해서 찾으면 -1,-1 fix 값 빼고 left,right 지정 후 mid = (l+r)/2 으로 찾으면 당연히 그냥 가능한 수열중 딱 하나를 빠르게 찾을 뿐이다.... 이러면 안되고 lower boundary의 끝 부분과 지금 수열에서 가능한 부분인 [5 번째 인덱스 자리 부터 ~ 10 번째 인덱스 자리까지 탐색해야한다.] upper boundary의 끝을 알아내면 된다.

 

N이 10000이니 풀 수 있는 방법이다. 최대 5억번 돌 수 있으니 이를 유념해야 할 거 같다.

 

코드


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main {
    static int arr[];
    public static void main(String[] args) throws Exception{
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

        StringTokenizer tk = new StringTokenizer(in.readLine()," ");

        int N = Integer.parseInt(tk.nextToken());

        arr = new int[N];

        tk = new StringTokenizer(in.readLine()," ");

        for(int i = 0; i < N; i++){
            arr[i] = Integer.parseInt(tk.nextToken());
        }

        Arrays.sort(arr);

        long cnt = 0;

        for (int i = 0; i < N; i++){
            for (int j = i + 1; j < N; j++){
                int sum = arr[i] + arr[j];
                int l = j + 1;
                int r = N;
                int left = lower_bound(l,r,sum);
                int right = upper_bound(l,r,sum);
                cnt += right - left;
            }
        }
        System.out.println(cnt);
    }

    private static int lower_bound(int l, int r, int sum) {
        while(l < r){
            int mid = (l + r) / 2;
            if(sum + arr[mid] >= 0){
                r = mid;
            }else{
                l = mid + 1;
            }
        }
        return l;
    }
    private static int upper_bound(int l, int r, int sum) {
        while(l < r){
            int mid = (l + r) / 2;
            if(sum + arr[mid] > 0){
                r = mid;
            }else{
                l = mid + 1;
            }
        }
        return l;
    }
}

 

 

3151번: 합이 0

Elly는 예상치 못하게 프로그래밍 대회를 준비하는 학생들을 가르칠 위기에 처했다. 대회는 정확히 3명으로 구성된 팀만 참가가 가능하다. 그러나 그녀가 가르칠 학생들에게는 큰 문제가 있었다.

www.acmicpc.net