zoukankan      html  css  js  c++  java
  • 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
    ",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
    ",ans);
    133     }
    134     return 0;
    135 }
  • 相关阅读:
    preventDefault
    YII2中的Html助手和Request组件
    yii2 输出json的方法
    FormData异步上传
    通过Ajax方式上传文件,使用FormData进行Ajax请求
    Yii设置Cache缓存的方法
    exif_imagetype() 函数在linux下的php中不存在
    Thinkphp整合各个功能
    PHP cURL库函数抓取页面内容
    javascript实现打印功能
  • 原文地址:https://www.cnblogs.com/dd-bond/p/11391771.html
Copyright © 2011-2022 走看看