pku 3714(最近点对)

 1 /*
 2 *  题目要求:求最近点对(一个点在station内,一个点在agent内) 
 3 */
 4 
 5 #include <cmath>
 6 #include <cstdio>
 7 #include <cstdlib>
 8 #include <iostream>
 9 #include <algorithm>
10 
11 using namespace std;
12 
13 const int N = 200005;
14 const double INF = 1e20;
15 
16 struct point {
17     int f;
18     double x;
19     double y;
20 }p[N];
21 int tmp[N];
22 
23 double dis(point A, point B) {
24     return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
25 }
26 
27 int cmp(const point &a, const point &b) {
28     if (a.x != b.x) return a.x < b.x;
29     return a.y < b.y;
30 }
31 
32 int cmp1(const int &a, const int &b) {
33     return p[a].y < p[b].y;
34 }
35 
36 double min(double a, double b) {
37     return a > b ? b : a;
38 }
39 
40 double closestPair(int left, int right) {
41     double d = INF;
42     if (left == right) return d;      //同属station点,返回无穷大 
43     if (left+1 == right) return d;    //同属agent点,返回无穷大
44     int mid = (left + right) >> 1;
45     double d1 = closestPair(left, mid);
46     double d2 = closestPair(mid+1, right);
47     d = min(d1, d2);
48     int k = 0;
49     for (int i=left; i<=right; ++i) {
50         if (fabs(p[mid].x- p[i].x) <= d) tmp[k++] = i;
51     }
52     sort(tmp, tmp+k, cmp1);
53     for (int i=0; i<k; ++i) {//只有当一个点为station的点,另一个点为agent点时,才计算两点距离 
54         for (int j=i+1; j<k && p[tmp[j]].y-p[tmp[i]].y<d && ((p[tmp[j]].f==0&&p[tmp[i]].f==1)||(p[tmp[j]].f==1&&p[tmp[i]].f==0)); ++j) {
55             double d3 = dis(p[tmp[i]], p[tmp[j]]);
56             if (d3 < d) d = d3;
57         }
58     }
59     return d;
60 } 
61 
62 int main() {
63     int n, t;
64     scanf ("%d", &t);
65     while (t--) {
66         scanf ("%d", &n);
67         for (int i=0; i<n; ++i) {
68             scanf ("%lf%lf", &p[i].x, &p[i].y);
69             p[i].f = 0;  //标志为station的点 
70         }
71         for (int i=n; i<n+n; ++i) {
72             scanf ("%lf%lf", &p[i].x, &p[i].y);
73             p[i].f = 1;  //标志为agent的点 
74         }
75         if (n == 1) printf ("%.lf\n", dis(p[0], p[1]));//只有两个点,直接算 
76         else {
77             sort(p, p+n+n, cmp);
78             double ans = closestPair(0, n+n-1);
79             printf ("%.3lf\n", ans);
80         } 
81     }
82     return 0;
83 }

 

转载于:https://www.cnblogs.com/try86/archive/2012/04/26/2472070.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值