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)=(xa−xb)2+(ya−yb)2

浙公网安备 33010602011771号