标签:
1 3 0 0 1 1 2 2
12HintIf palace $ (0,0) $ disappears,$ d = (1-2) ^ 2 + (1 - 2) ^ 2 = 2 $; If palace $ (1,1) $ disappears,$ d = (0-2) ^ 2 + (0 - 2) ^ 2 = 8 $; If palace $ (2,2) $ disappears,$ d = (0-1) ^ 2 + (0-1) ^ 2 = 2 $; Thus the answer is $ 2 + 8 + 2 = 12 $。
题目大意:给出平面上n个点的坐标,可以得到平面最近点对的距离。
现求分别删掉第1~n个点时,平面上最近点对的距离的和。(这里防止精度问题,只要求距离的平方
可知对于不删点时可以求得最近点对。
如果删掉的点不是最近点对的两个端点,最近距离还是这两个点的距离。(会有n-2)次
其次,如果删除其中任何一个点,标记一下,然后再分别跑一边最近点,统计即可。
最近点对用分治法,模板类。
此外注意开long long
代码如下:
#include <iostream> #include <cmath> #include <vector> #include <cstdlib> #include <cstdio> #include <cstring> #include <queue> #include <stack> #include <list> #include <algorithm> #include <map> #include <set> #define LL long long #define Pr pair<int,int> #define fread(ch) freopen(ch,"r",stdin) #define fwrite(ch) freopen(ch,"w",stdout) using namespace std; const LL INF = 0x3f3f3f3f3f3f3f3f; const int msz = 100100; const int mod = 1e9+7; const double eps = 1e-8; struct Point { LL x,y; int id; }; LL dist(Point a,Point b) { return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y); } Point p[msz]; Point tmpt[msz]; bool cmpxy(Point a,Point b) { if(a.x != b.x) return a.x < b.x; return a.y < b.y; } bool cmpy(Point a,Point b) { return a.y < b.y; } LL d; int pt[2]; void Closest_Pair(int left,int right,int opt) { if(left == right) return; LL tmp; if(left + 1 == right) { if(p[left].id != opt && p[right].id != opt) { tmp = dist(p[left],p[right]); if(d > tmp) { d = tmp; if(opt == -1) { pt[0] = p[left].id; pt[1] = p[right].id; } } } return; } int mid = (left+right)/2; Closest_Pair(left,mid,opt); Closest_Pair(mid+1,right,opt); int k = 0; for(int i = left; i <= right; ++i) { if(p[i].id != opt && abs(p[mid].x - p[i].x) <= d) tmpt[k++] = p[i]; } sort(tmpt,tmpt+k,cmpy); for(int i = 0; i < k; ++i) { for(int j = i+1; j < k && tmpt[j].y - tmpt[i].y < d; ++j) { tmp = dist(tmpt[i],tmpt[j]); if(d > tmp) { if(opt == -1) { pt[0] = tmpt[i].id; pt[1] = tmpt[j].id; } d = tmp; } } } } int main() { //fread(""); //fwrite(""); int t,n; scanf("%d",&t); while(t--) { scanf("%d",&n); for(int i = 0; i < n; ++i) { scanf("%lld%lld",&p[i].x,&p[i].y); p[i].id = i; } sort(p,p+n,cmpxy); d = INF; Closest_Pair(0,n-1,-1); LL ans = 1LL*d*(n-2); d = INF; Closest_Pair(0,n-1,pt[0]); ans += d; d = INF; Closest_Pair(0,n-1,pt[1]); ans += d; printf("%lld\n",ans); } return 0; }
标签:
原文地址:http://blog.csdn.net/challengerrumble/article/details/51945242