• bzoj1038题解


    【题意分析】

      求一个下凸壳与一段折线的距离。

    【解题思路】

      先把直线按斜率排序,求出下凸壳,然后枚举所有的顶点的x坐标求最短y坐标差,复杂度O(nlog2n)。

    【参考代码】

      1 #include <algorithm>
      2 #include <cstdio>
      3 #define REP(i,low,high) for(register int i=(low);i<=(high);++i)
      4 #define __function__(type) /*__attribute__((optimize("-O2"))) inline */type
      5 #define __procedure__ /*__attribute__((optimize("-O2"))) inline */void
      6 using namespace std;
      7  
      8 //defs {
      9 #include <cmath>
     10 template<typename real>
     11 inline __function__(bool) fequals(
     12     const real&one,const real&another,const real&eps=1e-6
     13 ) {return fabs(one-another)<eps;}
     14 template<typename real>
     15 inline __function__(bool) funequals(
     16     const real&one,const real&another,const real&eps=1e-6
     17 ) {return fabs(one-another)>=eps;}
     18 //} defs
     19  
     20 //geometry {
     21 template<typename T=double> struct Point
     22 {
     23     T x,y; Point(const T&_x=0,const T&_y=0):x(_x),y(_y) {}
     24     __function__(bool) operator==(const Point<T>&thr)const
     25     {
     26         return fequals(x,thr.x)&&fequals(y,thr.y);
     27     }
     28     __function__(bool) operator!=(const Point<T>&thr)const
     29     {
     30         return funequals(x,thr.x)||funequals(y,thr.y);
     31     }
     32     __function__(Point<T>) operator+(const Point<T>&thr)const
     33     {
     34         return Point<T>(x+thr.x,y+thr.y);
     35     }
     36     __function__(Point<T>) operator-(const Point<T>&thr)const
     37     {
     38         return Point<T>(x-thr.x,y-thr.y);
     39     }
     40     __function__(Point<T>) operator*(const T&lambda)const
     41     {
     42         return Point<T>(x*lambda,y*lambda);
     43     }
     44     __function__(Point<double>) operator/(const T&lambda)const
     45     {
     46         return Point<double>(double(x)/lambda,double(y)/lambda);
     47     }
     48     __function__(double) theta()const
     49     {
     50         return x>0?(y<0)*2*M_PI+atan(y/x):M_PI+atan(y/x);
     51     }
     52     __function__(double) theta_x()const{return x?atan(y/x):M_PI/2;}
     53     __function__(double) theta_y()const{return y?atan(x/y):M_PI/2;}
     54 };
     55 template<typename T>
     56 inline __function__(T) dot_product(const Point<T>&A,const Point<T>&B)
     57 {
     58     return A.x*B.x+A.y*B.y;
     59 }
     60 template<typename T>
     61 inline __function__(T) cross_product(const Point<T>&A,const Point<T>&B)
     62 {
     63     return A.x*B.y-A.y*B.x;
     64 }
     65 template<typename T>
     66 inline __function__(double) Euclid_distance(const Point<T>&A,const Point<T>&B)
     67 {
     68     return sqrt(pow(A.x-B.x,2),pow(A.y-B.y,2));
     69 }
     70 template<typename T>
     71 inline __function__(T) Manhattan_distance(const Point<T>&A,const Point<T>&B)
     72 {
     73     return fabs(A.x-B.x)+fabs(A.y-B.y);
     74 }
     75 struct kbLine
     76 {
     77     //line:y=kx+b
     78     double k,b; kbLine(const double&_k=0,const double&_b=0):k(_k),b(_b) {}
     79     __function__(bool) operator==(const kbLine&thr)const
     80     {
     81         return fequals(k,thr.k)&&fequals(b,thr.b);
     82     }
     83     __function__(bool) operator!=(const kbLine&thr)const
     84     {
     85         return funequals(k,thr.k)||funequals(b,thr.b);
     86     }
     87     __function__(bool) operator<(const kbLine&thr)const{return k<thr.k;}
     88     __function__(bool) operator>(const kbLine&thr)const{return k>thr.k;}
     89     template<typename T>
     90     __function__(bool) build_line(const Point<T>&A,const Point<T>&B)
     91     {
     92         return fequals(A.x,B.x)?0:(k=double(A.y-B.y)/(A.x-B.x),b=A.y-k*A.x,1);
     93     }
     94     __function__(double) theta_x()const{return atan(k);}
     95     __function__(double) theta_y()const{return theta_x()-M_PI/2;}
     96     __function__(double) get(const double&x)const{return k*x+b;}
     97 };
     98 __function__(bool) parallel(const kbLine&A,const kbLine&B)
     99 {
    100     return A!=B&&(fequals(A.k,B.k)||A.k!=A.k&&B.k!=B.k);
    101 }
    102 __function__(Point<double>*) cross(const kbLine&A,const kbLine&B)
    103 {
    104     if(A==B||parallel(A,B)) return NULL; double _x=double(B.b-A.b)/(A.k-B.k);
    105     Point<double>*ret=new Point<double>(_x,A.k*_x+A.b); return ret;
    106 }
    107 //} geometry
    108  
    109 static int n; double x[310],y[310]; int stack[310]; kbLine L[310];
    110  
    111 int main()
    112 {
    113     scanf("%d",&n); REP(i,1,n) scanf("%lf",x+i); REP(i,1,n) scanf("%lf",y+i);
    114     REP(i,1,n-1) L[i].build_line(Point<>(x[i],y[i]),Point<>(x[i+1],y[i+1]));
    115     sort(L+1,L+n); int top=stack[1]=1; REP(i,2,n-1)
    116     {
    117         for(;i<=n&&(L[i]==L[stack[top]]||parallel(L[i],L[stack[top]]));++i);
    118         for(;i<=n&&top>1;--top)
    119         {
    120             Point<>*last=cross(L[stack[top-1]],L[stack[top]]),
    121                    * now=cross(L[     i      ],L[stack[top]]);
    122             if(last->x<now->x) break; delete last; delete now;
    123         }
    124         stack[++top]=i;
    125     }
    126     double ans=1e10; int j=2;
    127     REP(i,1,n)
    128     {
    129         for(;L[stack[j]].get(x[i])>L[stack[j-1]].get(x[i]);++j);
    130         ans=min(ans,L[stack[--j]].get(x[i])-y[i]);
    131     }
    132     REP(i,2,top)
    133     {
    134         Point<>*now=cross(L[stack[i-1]],L[stack[i]]);
    135         j=upper_bound(x+1,x+n+1,now->x)-x; kbLine tmp;
    136         tmp.build_line(Point<>(x[j-1],y[j-1]),Point<>(x[j],y[j]));
    137         ans=min(ans,now->y-tmp.get(now->x)); delete now;
    138     }
    139     return printf("%.3lf
    ",ans),0;
    140 }
    View Code
  • 相关阅读:
    UU跑腿
    Java基础之接口与抽象类的区别
    经典面试题:Redis为什么这么快?
    isBlank与isEmpty
    阅读联机API文档
    从文本中取出链接地址 并检测链接地址能否打开
    2019-01-19=树莓派学习总结
    单片机知识点
    Linux 编程题
    嵌入式基础知识
  • 原文地址:https://www.cnblogs.com/spactim/p/6539612.html
Copyright © 2020-2023  润新知