#유형 : 분할 정복
# 간단한 알고리즘으로는 시간 초과를 벗어날 수 없음.. 풀었던 방법은
1) X좌표를 기준으로 정렬을 하여 middle index를 기준으로 왼쪽,오른쪽에서 가장 가까운 거리, middle 을 가로지르는 두 점간의 가장 가까운거리 3가지를 구해야 한다.
2) 왼쪽에서 가장 가까운 두점 사이의 거리, 오른쪽에서 가장 가까운 두점사이의 거리를 구하여 Min_value를 정해놓고, 이 값을 이용하여 middle index를 가로지르는 두 점간의 가장 가까운 거리를 구하여 min_value보다 작은 값들을 리스트에 넣는다.
3) 리스트를 Y좌표를 기준으로 정렬을 하여 y좌표들 간의 거리의 제곱이 stand보다 작은 값들만 거리를 구해서 비교하며 최솟값을 찾으면 된다.
package bj;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.StringTokenizer;
public class p2261 {
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
ArrayList arrList = new ArrayList<>();
StringTokenizer st;
for(int i=0; i<N; i++) {
st = new StringTokenizer(br.readLine());
int x = Integer.parseInt(st.nextToken());
int y= Integer.parseInt(st.nextToken());
arrList.add(new Point(x,y));
}
Collections.sort(arrList);
System.out.println(solve(arrList, 0, N-1));
}
static int solve(ArrayList p, int x, int y) {
int limit = y-x+1;
if(limit<=3)
return search(p, x, y);
int middle = (x+y)/2;
int left = solve(p, x, middle);
int right = solve(p, middle+1, y);
int stand = Math.min(left, right);
ArrayList tmp = new ArrayList<>();
for(int i=x; i<=y; i++) {
int dist = p.get(i).x - p.get(middle).x;
if(dist*dist < stand)
tmp.add(p.get(i));
}
Collections.sort(tmp, new point_compartor());
int size = tmp.size();
for(int i=0; i<size-1; i++) {
for(int j=i+1; j<size; j++) {
int val = tmp.get(i).y - tmp.get(j).y;
if(val*val < stand) {
int d = getDistance(tmp.get(i), tmp.get(j));
if(d < stand)
stand = d;
}else
break;
}
}
return stand;
}
public static int getDistance(Point p1, Point p2) {
int result = (int) (Math.pow(p1.x-p2.x, 2) + Math.pow(p1.y - p2.y, 2));
return result;
}
public static int search(ArrayList p, int x, int y) {
int rs = -1;
for(int i=x; i<=y-1; i++) {
for(int j=i+1; j<=y; j++) {
int val = getDistance(p.get(i), p.get(j));
if(rs==-1 || rs>val)
rs=val;
}
}
return rs;
}
public static class Point implements Comparable{
int x;
int y;
public Point(int x,int y) {
this.x=x;
this.y=y;
}
@Override
public int compareTo(Point o) {
int val = this.x - o.x;
if(val == 0) {
return this.y-o.y;
}else
return val;
}
}
public static class point_compartor implements Comparator{
@Override
public int compare(Point o1, Point o2) {
// TODO Auto-generated method stub
return o1.y-o2.y;
}
}
}
'백준' 카테고리의 다른 글
#백준_1208 부분수열의 합 2 - Java (0) | 2020.01.20 |
---|---|
#백준_1261 알고스팟 - Java (0) | 2020.01.19 |
#백준_1517 버블 소트 (0) | 2020.01.13 |
#백준_11404 플로이드 - Java (0) | 2020.01.11 |
백준_11657 타임머신 - Java 자바 (출력초과 수정완료) (0) | 2020.01.11 |