POJ-3714(最近点对)

Raid
Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 9745   Accepted: 2980

Description

After successive failures in the battles against the Union, the Empire retreated to its last stronghold. Depending on its powerful defense system, the Empire repelled the six waves of Union's attack. After several sleepless nights of thinking, Arthur, General of the Union, noticed that the only weakness of the defense system was its energy supply. The system was charged by N nuclear power stations and breaking down any of them would disable the system.

The general soon started a raid to the stations by N special agents who were paradroped into the stronghold. Unfortunately they failed to land at the expected positions due to the attack by the Empire Air Force. As an experienced general, Arthur soon realized that he needed to rearrange the plan. The first thing he wants to know now is that which agent is the nearest to any power station. Could you, the chief officer, help the general to calculate the minimum distance between an agent and a station?

Input

The first line is a integer T representing the number of test cases.
Each test case begins with an integer N (1 ≤ N ≤ 100000).
The next N lines describe the positions of the stations. Each line consists of two integers X (0 ≤ X ≤ 1000000000) and Y (0 ≤ Y ≤ 1000000000) indicating the positions of the station.
The next following N lines describe the positions of the agents. Each line consists of two integers X (0 ≤ X ≤ 1000000000) and Y (0 ≤ Y ≤ 1000000000) indicating the positions of the agent.  

Output

For each test case output the minimum distance with precision of three decimal placed in a separate line.

Sample Input

2
4
0 0
0 1
1 0
1 1
2 2
2 3
3 2
3 3
4
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0

Sample Output

1.414
0.000

题意:给两类点,求不同类点间的最短距离

思路:基础最近点对+判断是否是同类点

PS:G++貌似不能用%lf格式,C++可以

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <algorithm>
 5 #include <limits>
 6 using namespace std;
 7 
 8 #define maxn 100010
 9 #define EPS 0.000001
10 #define maxlen 2000000000
11 int n,t;
12 double d;//最近距离
13 int cp[2*maxn];//存中间部分的点的下标
14 struct node{
15     double x, y;
16     int kind;
17 }p[2*maxn];
18 
19 //两点间的欧式距离
20 double pdis(node& p1, node& p2){
21     return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
22 }
23 
24 //根据y坐标从小到大给点排序
25 bool cmpy(int a, int b){
26     return p[a].y > p[b].y;
27 }
28 
29 //根据x坐标从小到大给点排序
30 bool cmpx(node p1, node p2){
31     return p1.x < p2.x;
32 }
33 
34 //最近点对的主函数
35 inline void solve(int begin, int end){
36     if(begin == end) return;
37     int mid = (begin+end)/2;
38 
39     solve(begin, mid);
40     solve(mid + 1, end);
41 
42     //找出满足在p[mid]左右d范围内的所有点
43     double midx = p[mid].x;
44     int top = -1;
45     for (int i = begin; i <= end; i++){
46         if(fabs(midx - p[i].x) - d < -EPS)
47             cp[++top] = i;
48     }
49 
50     sort(cp, cp+top+1, cmpy);
51 
52     //向后查点,更新d值
53     for (int i = 0; i <= top; i++){
54         for(int j = i + 1; j <= i + 7 && j <= top; j++){
55             //判断两点是否同类,7个点之内如果没有符合条件的非同类点,说明其他非同类点与该点的距离大于d
56             if(p[cp[i]].kind != p[cp[j]].kind){
57                 double t = pdis(p[cp[i]],p[cp[j]]);
58                 if(t - d < -EPS) d = t;
59             }
60         }
61     }
62 }
63 
64 int main()
65 {
66     scanf("%d", &t);
67     while(t--){
68         scanf("%d", &n);
69         int i;
70         for (i = 0; i < n; i++){
71             scanf("%lf %lf", &p[i].x, &p[i].y);
72             p[i].kind = 1;
73         }
74         for ( ; i < 2*n; i++){
75             scanf("%lf %lf", &p[i].x, &p[i].y);
76             p[i].kind = 2;
77         }
78         sort(p, p+2*n, cmpx);
79         d = maxlen;
80         solve(0, 2*n-1);
81         printf("%.3lf\n", d);
82     }
83     return 0;
84 }

 

posted @ 2016-02-22 10:27  喷水小火龙  阅读(640)  评论(0)    收藏  举报