#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <cstring>
#include <sstream>
#include <map>
#include <stack>
#include <queue>
#include <ctime>
#include <cstdlib>
#define MAX 2000000000
using namespace std;
struct node{ //结构体
double x,y; // x,y坐标
int id; // 该变量用来表示 不同的集合
node(double x = -1,double y = -1,int id = 0){
this -> x = x;
this -> y = y;
this -> id = id;
};
bool operator < (const node &t1){ //重载 “<"
return this -> x < t1.x;
}
};
node *total;
double getdistance(node t1,node t2){ //求两点之间的距离
//cout << "---\n";
if(t1.x == t2.x && t2.y == t1.y)
return 0;
double v;
double x = (t1.x - t2.x) * (t1.x - t2.x);
double y = (t1.y - t2.y) * (t1.y - t2.y);
v = sqrt(x + y);
return v;
}
bool com(const node t1,const node t2){
return t1.y < t2.y;
}
//left_set: 左边集合 right_set: 右边集合。 d: 左,右集合中最小的距离。 mid : 分界点。 x: 分界点的x值。
double mid_dist(int start,int mid, int end,int d,double x){
node *s = new node[end - start + 1];
int cnt = 0;
for(int i = start; i <= end; i++)
if(abs(x - total[i].x) <= d)
s[cnt++] = total[i];
sort(s,s + cnt,com);
double len = MAX; //表示最小距离
int t = 0;
for(int i = 0; i < cnt; i++){
t = 0;
for(int j = i + 1; j < cnt && t <= 6 && abs(i - j) <= d; j++){
if(total[i].id != total[j].id){
t++;
len = min(len,getdistance(total[i],total[j]));
}
}
}
delete []s;
return len;
}
double minimumDist(int start,int end){ //求最短路径, 参数为排序后的所有点的集合。
if(start == end) return MAX; //小于2,直接返回最大值
if(end - start == 1){ //等于2,则计算路径长度
if(total[start].id != total[end].id) //不能为同一个集合。 否则也返回最大值
return getdistance(total[start],total[end]);
else
return MAX;
}
// vector<node> left_set,right_set; //平衡后的左边 和 右边
double left_dist,right_dist; //左边的最小距离 右边的最小距离
// int len = (start + end) / 2;
//划分左右
int mid = (start + end) / 2;;
// cout << start << " " << mid << " " << end << endl;
左边的最小距离 右边的最小距离
left_dist = minimumDist(start,mid);
right_dist = minimumDist(mid + 1, end);
//左右中比较小的一个。
double d = min(left_dist,right_dist);
//mid_dist() : 求中间的距离;
d = min(d,mid_dist(start,mid,end,d,total[mid].x));
// cout << left_dist << " " << right_dist << " " << d << endl;
return d;
}
int main(){
int n,k;
cin >> n;
while(n--){
cin >> k;
double x,y;
int i = 0;
total = new node[k * 2];
for(; i < k; i++){
cin >> x >> y;
total[i] = node(x,y,1);
}
for(; i < 2 * k; i++){
cin >> x >> y;
total[i] = node(x,y,2);
}
sort(total,total + i);
double dist = minimumDist(0,i - 1);
printf("%.3f\n",dist);
delete []total;
}
}
求平面内最近的点
最新推荐文章于 2022-05-07 16:47:44 发布