zoukankan      html  css  js  c++  java
  • 【POJ3525】Most Distant Point from the Sea-半平面交+二分答案

    测试地址:Most Distant Point from the Sea
    题目大意:给定一个凸多边形,求凸多边形内某点到各边的最小距离的最大值。
    做法:本题需要用到半平面交+二分答案。
    首先答案显然具有单调性,所以我们二分答案,转化成判定性问题。
    考虑答案d,我们只要将构成原凸多边形的半平面都向内缩d个单位长度,然后判定半平面交存不存在即可。因为不用排序,所以时间复杂度为O(n),配上外面的二分就多个log
    以下是本人代码:

    #include <bits/stdc++.h>
    #define eps 1e-12
    using namespace std;
    int n,bot,top;
    struct Point
    {
        double x,y;
    }p[110],zero;
    struct Line
    {
        Point a,b;
    }l[110],q[110];
    
    Point operator - (Point a,Point b)
    {
        Point s={a.x-b.x,a.y-b.y};
        return s;
    }
    
    double dis(Point a,Point b)
    {
        return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    }
    
    double multi(Point a,Point b)
    {
        return a.x*b.y-b.x*a.y;
    }
    
    Point inter(Line a,Line b)
    {
        double a1=multi(b.b-a.a,b.a-a.a),a2=multi(b.a-a.b,b.b-a.b);
        Point s={(a2*a.a.x+a1*a.b.x)/(a2+a1),(a2*a.a.y+a1*a.b.y)/(a2+a1)};
        return s;
    }
    
    bool JudgeOut(Point a,Line b)
    {
        return multi(a-b.a,b.b-b.a)>0.0;
    }
    
    bool solve()
    {
        q[1]=l[1],q[2]=l[2],bot=1,top=2;
        for(int i=3;i<=n;i++)
        {
            while (bot<top&&JudgeOut(inter(q[top-1],q[top]),l[i])) top--;
            while (bot<top&&JudgeOut(inter(q[bot],q[bot+1]),l[i])) bot++;
            q[++top]=l[i];
        }
        while (bot<top&&JudgeOut(inter(q[top-1],q[top]),q[bot])) top--;
        while (bot<top&&JudgeOut(inter(q[bot],q[bot+1]),q[top])) bot++;
    
        return top-bot>1;
    }
    
    int main()
    {
        zero.x=zero.y=0.0;
    
        while(scanf("%d",&n)&&n)
        {
            for(int i=1;i<=n;i++)
                scanf("%lf%lf",&p[i].x,&p[i].y);
            p[n+1]=p[1];
    
            double lft=0.0,rht=10000.0;
            while (rht-lft>eps)
            {
                double mid=(lft+rht)/2.0;
                for(int i=1;i<=n;i++)
                {
                    l[i].a.x=p[i].y-p[i+1].y,l[i].a.y=p[i+1].x-p[i].x;
                    double r=mid/dis(zero,l[i].a);
                    l[i].a.x*=r,l[i].a.y*=r;
                    l[i].a.x+=p[i].x,l[i].a.y+=p[i].y;
                    l[i].b.x=l[i].a.x+p[i+1].x-p[i].x;
                    l[i].b.y=l[i].a.y+p[i+1].y-p[i].y;
                }
                if (solve()) lft=mid;
                else rht=mid;
            }
    
            printf("%.6f
    ",lft);
        }
    
        return 0;
    }
  • 相关阅读:
    批量修改图片尺寸
    批量修改文件名
    C++ 字符串的编码
    Hanoi问题
    农夫过河问题
    遍历文件夹中所有图片
    仿射变换和透射变换
    程序局部性原理
    14年年底的学习计划
    linux之Vim使用
  • 原文地址:https://www.cnblogs.com/Maxwei-wzj/p/9793524.html
Copyright © 2011-2022 走看看