zoukankan      html  css  js  c++  java
  • uva1396,poj3525半平面交+二分

    链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=533&page=show_problem&problem=4142

    提议:海中一个凸多边形小岛,求出岛上离海最远点到海的距离。

    思路:就是求这个凸多边形内切圆的最大半径。对半径进行二分,将多边形所有边向内平移半径的长度,然后求半平面交,如果有交则有满足的点。

     在poj上用g++交wa了,c++又过了。。。坑

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn=200;
    const double eps=1e-8;
    struct Point
    {
        double x,y;
        Point(double x=0,double y=0):x(x),y(y) {}
    };
    typedef Point Vector;
    struct DLine
    {
        Point P;
        Vector v;
        double ang;
        DLine() {}
        DLine(Point P,Vector v):P(P),v(v)
        {
            ang=atan2(v.y,v.x);
        }
        bool operator < (const DLine& L) const
        {
            return ang<L.ang;
        }
    };
    Vector operator + (Vector A,Vector B)
    {
        return Vector(A.x+B.x,A.y+B.y);
    }
    Vector operator - (Vector A,Vector B)
    {
        return Vector(A.x-B.x,A.y-B.y);
    }
    Vector operator * (Vector A,double p)
    {
        return Vector(A.x*p,A.y*p);
    }
    int dcmp(double x)
    {
        if(fabs(x)<eps) return 0;
        else return x<0?-1:1;
    }
    bool operator == (const Point& a,const Point& b)
    {
        return dcmp(a.x-b.x)==0 && dcmp(a.y-b.y)==0;
    }
    double Dot(Vector A,Vector B)
    {
        return A.x*B.x+A.y*B.y;
    }
    double Length(Vector A)
    {
        return sqrt(Dot(A,A));
    }
    double Cross(Vector A,Vector B)
    {
        return A.x*B.y-A.y*B.x;
    }
    Vector Normal(Vector A)//向量的单位法线,即左转90度
    {
        double L=Length(A);
        return Vector(-A.y/L,A.x/L);
    }
    bool OnLeft(DLine L,Point p)
    {
        return Cross(L.v,p-L.P)>0;
    }
    Point GetIntersection(DLine a,DLine b)
    {
        Vector u=a.P-b.P;
        double t=Cross(b.v,u)/Cross(a.v,b.v);
        return a.P+a.v*t;
    }
    int HalfPlaneIntersection(DLine* L,int n){
        sort(L,L+n);
        int first,last;
        Point *p=new Point[n];
        DLine *q=new DLine[n];
        q[first=last=0]=L[0];
        for(int i=1; i<n; i++)
        {
            while(first<last && !OnLeft(L[i],p[last-1])) last--;
            while(first<last && !OnLeft(L[i],p[first])) first++;
            q[++last]=L[i];
            if(fabs(Cross(q[last].v,q[last-1].v))<eps)
            {
                last--;
                if(OnLeft(q[last],L[i].P)) q[last]=L[i];
            }
            if(first<last) p[last-1]=GetIntersection(q[last-1],q[last]);
        }
        while(first<last && !OnLeft(q[first],p[last-1])) last--;
        if(last-first <= 1) return 0;
        p[last]=GetIntersection(q[last],q[first]);
        return (last-first+1);
    }
    int n;
    Point p[maxn];
    DLine l[maxn];
    Vector v[maxn],v2[maxn];
    void solve()
    {
        double left=0,right=10000;//二分
        while(right-left>1e-6)
        {
            double mid=left+(right-left)/2;
            for(int i=0; i<n; i++)
                l[i]=DLine(p[i]+v2[i]*mid,v[i]);
            int m=HalfPlaneIntersection(l,n);
            if(!m) right=mid;
            else left=mid;
        }
        printf("%.6lf
    ",left);
    }
    
    int main()
    {
       // freopen("in.cpp","r",stdin);
        while(scanf("%d",&n) && n)
        {
            for(int i=0; i<n; i++)
                scanf("%lf%lf",&p[i].x,&p[i].y);
            for(int i=0; i<n; i++)
            {
                v[i]=p[(i+1)%n]-p[i];
                v2[i]=Normal(v[i]);
            }
            solve();
        }
        return 0;
    }
  • 相关阅读:
    C++ 课程设计——电梯调度系统
    PAT 1006 Sign In and Sign Out 查找元素
    PAT 1005 Spell It Right 字符串处理
    C++ 词汇表
    四六级分数竟是这样算出来的!交白卷都不会得零分 (转)
    以太坊智能合约部署
    如何设计一个通证经济体系?(转载)
    以太坊上那些暴力“利”的应用(转载)
    geth搭建以太坊私链及常用操作
    ubuntu18.04 安装 QQ
  • 原文地址:https://www.cnblogs.com/54zyq/p/3238943.html
Copyright © 2011-2022 走看看