您的位置:首页 > 大数据 > 人工智能

POJ 3714 Raid 最近点对

2015-01-24 21:04 253 查看
题意:有N个士兵,N个炮台。给出这2N个点的坐标,求士兵距离炮台的最近距离。

思路:最近点对问题。因为有两种点,我们只需求出这两种点之间的最短距离。

在算法中,我们对两种点给不同的标记,然后计算不同标记点的距离即可。

#include <cstdio>
#include <algorithm>
#include <utility>
#include <cmath>
#include <vector>

using namespace std;

const int MAX = 300010;

struct point{
double x,y,t;
point(){}
point(double xx, double yy, int tt):x(xx),y(yy),t(tt){}
bool operator < (const point & rhs) const{
return x  < rhs.x;
}
};

bool cmp(const point & lhs, const point & rhs){
return lhs.y < rhs.y;
}

point p[MAX];
int N,T,sz;

double solve(point * a, int n)
{
if(n <= 1) return 0x6f6f6f6f;
int m = n / 2;
double x = a[m].x;
double d = min(solve(a,m),solve(a+m,n-m));
inplace_merge(a,a+m,a+n,cmp);

vector<point> b;
for(int i = 0; i < n; ++i){
if(fabs(a[i].x - x) >= d) continue;
if(a[i].t == 1)
b.push_back(a[i]);
else{
for(int j = 0, sz = b.size(); j < sz; ++j){
double dx = a[i].x - b[sz - j - 1].x;
double dy = a[i].y - b[sz - j - 1].y;
if(dy >= d) break;
d = min(d,sqrt(dx * dx + dy * dy));
}
}
}
return d;
}

int main(void)
{
//freopen("input.txt","r",stdin);
scanf("%d",&T);
while(T--){
sz = 0;
scanf("%d",&N);
double x,y;
for(int i = 0; i < N; ++i){
scanf("%lf%lf",&x,&y);
p[sz++] = point(x,y,1);
}
for(int i = 0; i < N; ++i){
scanf("%lf%lf",&x,&y);
p[sz++] = point(x,y,2);
}
sort(p,p + 2 * N);
printf("%.3f\n",solve(p,2 * N));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: