zoukankan      html  css  js  c++  java
  • UVA 3890 Most Distant Point from the Sea(二分法+半平面交)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=11358

    【思路】

           二分法+半平面交

           二分与海边的的距离,由法向量可以得到平移后的各边,半平面交在特定精度判断是否有交集。

    【代码】

     1 #include<cmath>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 
     7 const double eps = 1e-7;
     8 
     9 struct Pt {
    10     double x,y;
    11     Pt(double x=0,double y=0):x(x),y(y) {}
    12 };
    13 typedef Pt vec;
    14 struct Line {
    15     Pt P; vec v;
    16     double ang;
    17     Line () {};
    18     Line (Pt P,vec v):P(P),v(v) { ang=atan2(v.y , v.x); }
    19     bool operator < (const Line& rhs) const{
    20         return ang<rhs.ang;
    21     }
    22 };
    23 
    24 vec operator - (Pt A,Pt B) { return vec(A.x-B.x,A.y-B.y); }
    25 vec operator + (vec A,vec B) { return vec(A.x+B.x,A.y+B.y); }
    26 vec operator * (vec A,double p) { return vec(A.x*p,A.y*p); }
    27 double Dot(vec A,vec B) { return A.x*B.x+A.y*B.y; }
    28 double cross(Pt A,Pt B) { return A.x*B.y-A.y*B.x; }
    29 double Len(vec A) { return sqrt(Dot(A,A)); }
    30 vec Normal(vec A) { double L=Len(A); return vec(-A.y/L,A.x/L); }
    31 
    32 bool onleft(Line L,Pt P) { return cross(L.v,P-L.P)>0; }
    33 
    34 Pt LineIntersection(Line a,Line b) {
    35     vec u=a.P-b.P;
    36     double t=cross(b.v,u)/cross(a.v,b.v);
    37     return a.P+a.v*t;
    38 }
    39 int HalfplaneIntersection(Line* L,int n,Pt* poly) {
    40     sort(L,L+n);
    41     int first,last;
    42     Pt *p=new Pt[n];
    43     Line *q=new Line[n];
    44     q[first=last=0]=L[0];
    45     for(int i=1;i<n;i++) {
    46         while(first<last && !onleft(L[i],p[last-1])) last--;
    47         while(first<last && !onleft(L[i],p[first])) first++;
    48         q[++last]=L[i];
    49         if(fabs(cross(q[last].v,q[last-1].v))<eps) {
    50             last--;
    51             if(onleft(q[last],L[i].P)) q[last]=L[i];
    52         }
    53         if(first<last) p[last-1]=LineIntersection(q[last-1],q[last]);
    54     }
    55     while(first<last && !onleft(q[first],p[last-1])) last--;
    56     if(last-first<=1) return 0;
    57     p[last]=LineIntersection(q[last],q[first]);
    58     int m=0;
    59     for(int i=first;i<=last;i++) poly[m++]=p[i];
    60     return m;
    61 }
    62 
    63 const int N = 200+10;
    64 Pt p[N],poly[N];
    65 Line L[N];
    66 vec v[N] , v2[N]; 
    67 int n;
    68 
    69 int main() {
    70     while(scanf("%d",&n)==1 && n) {
    71         int m,x,y;
    72         for(int i=0;i<n;i++) {
    73             scanf("%d%d",&x,&y);
    74             p[i]=Pt(x,y);
    75         }
    76         for(int i=0;i<n;i++) {
    77             v[i]=p[(i+1)%n]-p[i];
    78             v2[i]=Normal(v[i]);
    79         }
    80         double left=0 , right=20000;
    81         while(right-left>eps) {
    82             double mid=left+(right-left)/2;
    83             for(int i=0;i<n;i++) L[i]=Line(p[i]+v2[i]*mid,v[i]);
    84             m=HalfplaneIntersection(L,n,poly);
    85             if(!m) right=mid; else left=mid;
    86         }
    87         printf("%.6lf
    ",left);
    88     }
    89     return 0;
    90 }
  • 相关阅读:
    前端脚手架的那些事儿
    CSS重置默认样式reset.css代码模板
    Web 3.0 前瞻:基于区块链的下一代浏览器
    关键词定位是网站推广的基础
    6年架构师针对web前端小白,作出的职业规划建议
    和程序员约会的优点和缺点
    如何在软件开发中避免出现漏洞
    Linux下修改时区
    前端需要掌握的Nginx知识
    Nginx入门指南
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5176694.html
Copyright © 2011-2022 走看看