标签:
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