Link


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

Detail


점 개수가 100000이다. 으로 풀 수 없는 문제다.

Sweeping 기법을 사용해서 문제를 해결한다면 다음과 같은 과정을 거친다.

  • 모든 좌표를 x값 기준으로 정렬한다.
  • Min_dist 값 하나를 잡아두고 스위핑을 돌린다. 이 값보다 x값이 차이가 나면 left를 끌어올린다.
    • Right값을 하나 갱신해 줄 때마다, 추가되는 후보 점들을 set에 y좌표 기준으로 정렬해서 넣어둔다.
    • 추가로 Min_dist값 이내에 해당되는 값들만 binary_search로 찾아서 값을 추가한다.

시간 복잡도 =

Code


#include<bits/stdc++.h>
 
using namespace std;
 
using pos = pair<int, int>;
using ll = long long;
 
pos inline get_input() {
    pos new_pos;
    cin >> new_pos.first >> new_pos.second;
    return new_pos;
}
 
pos inline flip(const pos& ori) {
    return make_pair(ori.second, ori.first);
}
 
ll inline dist_sqr(const pos& one, const pos& two) {
    ll dx = (ll)one.first - two.first;
    ll dy = (ll)one.second - two.second;
    return dx*dx + dy*dy;
}
 
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr); cout.tie(nullptr);
    
    int n; cin >> n;
    
    vector<pos> dots(n);
    set<pos> y_sorted;
    for(auto& p : dots) {
        p = get_input();
    }
       
    // start sweeping
    sort(dots.begin(), dots.end());
    
    y_sorted.insert(flip(dots[0]));
    y_sorted.insert(flip(dots[1]));
    ll min_dist = dist_sqr(dots[0], dots[1]);
    
    int l = 0, r = 1;
    for(r = 2; r < n; r++){
        
        // x값의 차이가 min_dist 이내인 값들로만 스위핑 영역 구성
        while(l < r) {
            ll x_diff = dots[r].first - dots[l].first;
            if(x_diff * x_diff <= min_dist) break;
            
            y_sorted.erase(flip(dots[l++]));
        }
        
        // y값이 min_dist이내인 애들로만 작성
        ll sqrt_dist = static_cast<ll>(sqrt(min_dist));
        pos hi = {dots[r].second + sqrt_dist, INT_MAX};
        pos lo = {dots[r].second - sqrt_dist, INT_MIN};
        auto top_iter = y_sorted.upper_bound(hi);
        auto btm_iter = y_sorted.lower_bound(lo);
        
        for(auto it = btm_iter; it != top_iter; it++) {
            ll dist = dist_sqr(flip(*it), dots[r]);
            min_dist = min(min_dist, dist);
        }
        
        // 비교대상 영역에 r값 추가
        y_sorted.insert(flip(dots[r]));
    }
    
    cout << min_dist << '\n';
    
    
    return 0;
}