본문 바로가기

알고리즘 · 코딩

[백준 5620번] 가장 가까운 두 점의 거리

문제 링크

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

 

5620번: 가장 가까운 두 점의 거리

평면상에 n개의 점 (P1, .... ,  Pn) 이 놓여져있다고 했을 때, 거리가 최소인 두 개의 점을 구하고 그 거리를 알고 싶다.

www.acmicpc.net


C++ 풀이

#include <iostream>
#include <vector>
#include <algorithm>
#include <math.h>
using namespace std;

struct Point {
	int x;
	int y;
};

vector <Point>  points;
long long closest_dist;

// 두 점 사이 간의 거리 제곱값
long long dist(Point a, Point b) {
	return (((long long)b.x - a.x) * ((long long)b.x - a.x)) + (((long long)b.y - a.y) * ((long long)b.y - a.y));
}

// x좌표 오름차순 정렬
bool x_cmp(Point a, Point b) {
	if (a.x < b.x)
		return true;

	return false;
}

// Line Sweeping 방식으로 풀이
// 현재 점(idx) 기준으로 x거리 차이가 지금까지 구한 최소 거리보다 작은 점들의 거리만 구함
void find_closest(int idx) {
	double sqrt_dist = sqrt(closest_dist);
	long long d;

	// 현재 점보다 왼쪽에 위치한 점들
	for (int i = idx - 1; i >= 0; --i) {
		if ((double)points[idx].x - points[i].x < sqrt_dist) {
			d = dist(points[idx], points[i]);

			// 최소 거리 갱신
			if (d < closest_dist)
				closest_dist = d;
		}
		else
			break;
	}

	// 현재 점보다 오른쪽에 위치한 점들
	for (int i = idx + 1; i < points.size(); ++i) {
		if ((double)points[i].x - points[idx].x < sqrt_dist) {
			d = dist(points[idx], points[i]);

			// 최소 거리 갱신
			if (d < closest_dist)
				closest_dist = d;
		}
		else
			break;
	}
}

int main() {
	int N;
	cin >> N;
	points.resize(N);
	for (int n = 0; n < N; ++n)
		cin >> points[n].x >> points[n].y;
	sort(points.begin(), points.end(), x_cmp); //x좌표 기준 오름차순으로 정렬
    
	// 초기 최소 거리 값을 가장 x값이 작은 두 점 간의 거리로 설정
	closest_dist = dist(points[0], points[1]);
    
	for (int i = 0; i < N; ++i)
		find_closest(i);
	cout << closest_dist << endl;	
	return 0;
}

Line Sweeping 알고리즘을 활용하여 풀었다.

x축 기준으로 오름차순 정렬을 한 뒤, 앞에서부터 차례대로 아래 과정을 반복했다.

 

i - 1 번째 까지의 가장 가까운 두 점 간의 거리를 closest_dist라 할 때,

i 번째 점을 기준으로 왼쪽 점들, 오른쪽 점들 중 x좌표 차이가 closest_dist보다 작은 점들에 대해서만 거리를 구한다.

만약 구한 거리가 closest_dist보다 작을 경우, closest_dist를 구한 거리 값으로 갱신한다.

 

 

반응형

'알고리즘 · 코딩' 카테고리의 다른 글

[프로그래머스] n^2 배열 자르기  (0) 2021.12.23
[프로그래머스] 전력망을 둘로 나누기  (0) 2021.12.22
[SWEA 1249] 보급로  (0) 2021.10.27
[SWEA 1230] 암호문3  (0) 2021.10.27
[SWEA 1215] 회문1  (0) 2021.10.21