알고리즘/[ Baekjoon ]

[ BOJ ][JAVA][2261] 가장 가까운 두 점

kim.svadoz 2021. 4. 22. 23:49
반응형

www.acmicpc.net/problem/2261

 

2261번: 가장 가까운 두 점

첫째 줄에 자연수 n(2 ≤ n ≤ 100,000)이 주어진다. 다음 n개의 줄에는 차례로 각 점의 x, y좌표가 주어진다. 각각의 좌표는 절댓값이 10,000을 넘지 않는 정수이다. 여러 점이 같은 좌표를 가질 수도

www.acmicpc.net

시간 제한 메모리 제한 제출 정답 맞은 사람 정답 비율
1 초 256 MB 25345 4234 2120 15.700%

문제

2차원 평면상에 n개의 점이 주어졌을 때, 이 점들 중 가장 가까운 두 점을 구하는 프로그램을 작성하시오.

입력

첫째 줄에 자연수 n(2 ≤ n ≤ 100,000)이 주어진다. 다음 n개의 줄에는 차례로 각 점의 x, y좌표가 주어진다. 각각의 좌표는 절댓값이 10,000을 넘지 않는 정수이다. 여러 점이 같은 좌표를 가질 수도 있다.

출력

첫째 줄에 가장 가까운 두 점의 거리의 제곱을 출력한다.

예제 입력 1

4
0 0
10 10
0 10
10 0

예제 출력 1

100

코드

import java.io.*;
import java.util.*;
public class p2261 {
    static BufferedReader br;
    static BufferedWriter bw;
    static StringTokenizer st;
    static int n;
    static Pair[] pair;
    public static void main(String[] args) throws IOException {
        br = new BufferedReader(new InputStreamReader(System.in));
        bw = new BufferedWriter(new OutputStreamWriter(System.out));
        n = Integer.parseInt(br.readLine());

        pair = new Pair[n];
        for (int i = 0; i < n; ++i) {
            st = new StringTokenizer(br.readLine());
            int x = Integer.parseInt(st.nextToken());
            int y = Integer.parseInt(st.nextToken());
            pair[i] = new Pair(x, y);
        }
        // 최소거리 구하기 위해 x값 오름차순 정렬
        Arrays.sort(pair, (a, b) -> (a.x - b.x));
        // TreeSet에 들어가는 Pair의 y값이 같으면 x값이 오름차순, 다르다면 y값이 오름차순
        TreeSet<Pair> set = new TreeSet<>((a, b) -> ((a.y == b.y) ? a.x - b.x : a.y - b.y));


        set.add(pair[0]);
        set.add(pair[1]);
        // 두 점 사이의 거리를 최단거리라고 가정하고 시작
        // 기준이 되는 0과 가장 가까운 1의 거리를 구한다.
        long answer = dist(pair[0], pair[1]);
        int start = 0;
        for (int i = 2; i < n; ++i) {
            Pair cur = pair[i];
            // set에 있는 점들의 유효성 검사
            while (start < i) {
                Pair p = pair[start];
                long x = cur.x - p.x;
                if (x * x > answer) { // x 축의 차이가 최단거리보다 크다면 비교할 필요가 없기때문에 set에서 삭제
                    set.remove(p);
                    start ++;
                } else { 
                    break;
                }
            }
            // 최단거리
            int d = (int) Math.sqrt((double) answer) + 1;
            // y값의 범위를 계산
            Pair from = new Pair(-10001, cur.y - d);
            Pair to = new Pair(10001, cur.y + d);

            // subSet() 메소드는 첫 번째 매개변수로 전달된 값에 해당하는 요소부터 시작하여
            // 두 번째 매개변수로 전달된 값에 해당하는 요소의 바로 직전 요소까지를 반환
            for (Pair pair : set.subSet(from, to)) {
                long distance = dist(cur, pair);
                answer = Math.min(answer, distance);
            }
            set.add(cur);
        }
        /*
        for(int i = 0; i < n; ++i) {
            bw.write(pair[i].x + " " + pair[i].y + "\n");
        }
        */
        bw.write(answer+"\n");
        bw.flush();
        br.close();
        bw.close();
    }

    static long dist(Pair A, Pair B) {
        return (long) (Math.pow(A.x - B.x, 2) + Math.pow(A.y - B.y, 2));
    }

    static class Pair{
        int x, y;
        Pair (int x, int y) {
            this.x = x;
            this.y = y;
        }

    }
}
반응형

'알고리즘 > [ Baekjoon ]' 카테고리의 다른 글

[ BOJ ][JAVA][2294] 동전 2  (0) 2021.04.22
[ BOJ ][JAVA][2293] 동전 1  (0) 2021.04.22
[ BOJ ][JAVA][1106] 호텔  (0) 2021.04.22
[ BOJ ][JAVA][1949] 우수마을  (0) 2021.04.22
[ BOJ ][JAVA][1922] 네트워크 연결  (0) 2021.04.22