HDU 6697 Closest Pair of Segments(线段距离)
Posted dd-bond
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 6697 Closest Pair of Segments(线段距离)相关的知识,希望对你有一定的参考价值。
首先最容易想到的就是N2暴力枚举所有线段去找最小值,但是这样会做了许多无用功。我们可以先对线段排序,使得线段最左侧的端点按照x轴y轴排序,然后我们可以限定在这个线段的矩形框内的所有线段才有可能产生最小值,每次查询对于第i条线段的最近距离,如果第j条线段的最左侧点的x与第i条线段的最右侧点的x差值大于ans,那么可以直接break,之后枚举是没有任何意义的,一定会大于ans,所以加了这部分剪枝复杂度就压缩了很大部分。
1 // ——By DD_BOND 2 3 //#include<bits/stdc++.h> 4 //#include<unordered_map> 5 //#include<unordered_set> 6 #include<functional> 7 #include<algorithm> 8 #include<iostream> 9 //#include<ext/rope> 10 #include<iomanip> 11 #include<climits> 12 #include<cstring> 13 #include<cstdlib> 14 #include<cstddef> 15 #include<cstdio> 16 #include<memory> 17 #include<vector> 18 #include<cctype> 19 #include<string> 20 #include<cmath> 21 #include<queue> 22 #include<deque> 23 #include<ctime> 24 #include<stack> 25 #include<map> 26 #include<set> 27 28 #define fi first 29 #define se second 30 #define MP make_pair 31 #define pb push_back 32 33 #pragma GCC optimize(3) 34 #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") 35 36 using namespace std; 37 38 typedef long long ll; 39 40 const int MAXN=1e5+10; 41 const double eps=1e-8; 42 const double pi=acos(-1.0); 43 const ll INF=0x3f3f3f3f3f3f3f3f; 44 45 inline int dcmp(double x) 46 if(fabs(x)<eps) return 0; 47 return (x>0? 1: -1); 48 49 50 inline double sqr(double x) return x*x; 51 52 struct Point 53 double x,y; int id; 54 Point() x=0,y=0; 55 Point(double _x,double _y):x(_x),y(_y) 56 void input() scanf("%lf%lf",&x,&y); 57 void output() printf("%.2f %.2f\n",x,y); 58 inline bool operator <(const Point &b)const 59 return (dcmp(x-b.x)==0? dcmp(y-b.y)<0 : x<b.x); 60 61 inline Point operator -(const Point &b)const 62 return Point(x-b.x,y-b.y); 63 64 inline double len2() //长度平方 65 return sqr(x)+sqr(y); 66 67 inline double len() //长度 68 return sqrt(len2()); 69 70 ; 71 72 inline double cross(Point a,Point b) //叉积 73 return a.x*b.y-a.y*b.x; 74 75 76 inline double dot(Point a,Point b) //点积 77 return a.x*b.x+a.y*b.y; 78 79 80 inline double dis(Point a,Point b) //两点的距离 81 Point p=b-a; return p.len(); 82 83 84 struct Line 85 Point s,e; 86 Line() 87 Line(Point _s,Point _e):s(_s),e(_e) //两点确定直线 88 void input() 89 s.input(); 90 e.input(); 91 92 double length() 93 return dis(s,e); 94 95 ; 96 97 inline double point_to_line(Point p,Line a) //点到直线距离 98 return fabs(cross(p-a.s,a.e-a.s)/a.length()); 99 100 101 inline double point_to_seg(Point p,Line a) //点到线段距离 102 if(dcmp(dot(p-a.s,a.e-a.s))<0||dcmp(dot(p-a.e,a.s-a.e))<0) 103 return min(dis(p,a.e),dis(p,a.s)); 104 return point_to_line(p,a); 105 106 107 inline double seg_to_seg(Line u,Line v) 108 return min( min(point_to_seg(u.s,v),point_to_seg(u.e,v)), min( point_to_seg(v.s,u),point_to_seg(v.e,u)) ); 109 110 111 Line line[MAXN]; 112 113 bool cmp(Line a,Line b) 114 return a.s<b.s; 115 116 117 int main(void) 118 int T; scanf("%d",&T); 119 while(T--) 120 int n; scanf("%d",&n); 121 for(int i=0;i<n;i++) 122 line[i].input(); 123 if(line[i].e<line[i].s) swap(line[i].s,line[i].e); 124 125 sort(line,line+n,cmp); 126 double ans=1e10; 127 for(int i=0;i<n;i++) 128 for(int j=i+1;j<n;j++) 129 if(dcmp(line[j].s.x-line[i].e.x-ans)>0) break; 130 ans=min(ans,seg_to_seg(line[i],line[j])); 131 132 printf("%.12f\n",ans); 133 134 return 0; 135
以上是关于HDU 6697 Closest Pair of Segments(线段距离)的主要内容,如果未能解决你的问题,请参考以下文章
UVA - 10245 The Closest Pair Problem
UVa 10245 - The Closest Pair Problem
Java Find Closest Pair in Dataset 给出 NullPointerException [重复]