P7883 平面最近点对(加强加强版)

原题

充分发挥人类智慧,高唱人类赞歌。

站在出题人的角度思考问题。

首先我们考虑两个点的距离公式:

 由此看用x * y作排序键值较为合适。

为防止有点在坐标轴上,我们可以使每个点向坐上偏移某一个值,这里我采用的是1919

排完序之后,使用“智慧法”,我们往后查找 k 个点。经过不断的调试,k在200左右较为合适,超了会TLE。

代码如下:

 

#include<bits/stdc++.h>
using namespace std;

long long ans = 4611686018427387904ll;
int n;

struct node{
    long long x,y;
}a[400001];

bool cmp(node a,node b){
    return (a.x + 1919) * (a.y + 1919) > (b.x + 1919) * (b.y + 1919);
}

int main(){
    scanf("%d",&n);
    for(int i = 1; i <= n;++ i){
        scanf("%lld %lld",&a[i].x,&a[i].y);
    }
    sort(a + 1, a + 1 + n,cmp);
    for(int i = 1; i <= n;++ i){
        for(int j = i + 1; j <= min(i + 233,n);++ j){
            ans = min(ans,(a[i].x - a[j].x) * (a[i].x - a[j].x) + (a[i].y - a[j].y) * (a[i].y - a[j].y));
        }
    }
    for(int i = 1; i <= 50;++ i){
        for(int j = n; j >= max(i + 1, n - 50);-- j){
            ans = min(ans,(a[i].x - a[j].x) * (a[i].x - a[j].x) + (a[i].y - a[j].y) * (a[i].y - a[j].y));
        }
    }
    printf("%lld", ans);
    return 0;
}

 

则152组数据顺利AC。

学会了如何乱搞,受益颇多。

 

dist(a,b)=(xaxb)2+(yayb)2
posted @ 2024-01-21 21:57  Qwehhh  阅读(20)  评论(0)    收藏  举报