ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

POJ3525 Most Distant Point from the Sea

2019-02-10 19:41:17  阅读:337  来源: 互联网

标签:return Point db cross Most Distant vec poi line


半平面交+二分

二分最远距离把每个直线往里移这个距离然后看一下半平面交是否存在就好

然后注意精度问题 【poj G++需要用%f C++没有问题

//Love and Freedom.
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define inf 20021225
#define ll long long
#define db double
#define eps 1e-6
#define N 1010
using namespace std;

struct poi
{
    db x,y;
    poi(){}
    poi(db _x,db _y){x=_x,y=_y;}
};

typedef poi vec;

vec operator +(vec a,vec b){return vec(a.x+b.x,a.y+b.y);}
vec operator -(vec a,vec b){return vec(a.x-b.x,a.y-b.y);}
vec operator *(vec a,db b){return vec(a.x*b,a.y*b);}
db cross(vec a,vec b){return a.x*b.y-a.y*b.x;}
db dis(vec a){return sqrt(a.x*a.x+a.y*a.y);}

struct line
{
    poi p; vec v; db ang;
    line(){}
    line(poi p1,poi p2){p=p1; v=p2-p1; ang=atan2(v.y,v.x);}
}r[N],l[N];
void put(poi a)
{
    printf("%lf %lf\n",a.x,a.y);
}
void putl(line l)
{
    printf("----line----\n");
    put(l.p); put(l.v); printf("%lf\n",l.ang);
}
poi section(line a,line b)
{
    db k = cross(a.p-b.p,a.p+a.v-b.p)/(cross(a.p-b.p,b.v)+cross(b.v,a.p+a.v-b.p));
    return b.p+b.v*k;
}
bool onleft(line a,poi b){return cross(a.p+a.v-b,a.p-b)<eps;}
int n,stk[N],hd,tl; poi sec[N],pt[N];// bool azy = 1;
bool halfplane()//presort!
{
    stk[hd=tl=1] = 1;
    for(int i=2;i<=n;i++)
    {
        while(hd<tl && !onleft(l[i],sec[tl-1]))    tl--;
        while(hd<tl && !onleft(l[i],sec[hd]))    hd++;
        sec[tl] = section(l[i],l[stk[tl]]); stk[++tl] = i;
    }
    //sec[tl] = section(l[stk[hd]],l[stk[tl]]);
    while(hd<tl && !onleft(l[stk[hd]],sec[tl-1]))
        tl--;
    //printf("%d %d\n",hd,tl);
    if(hd+1<tl)    return true;
    return false;
}
line movein(line l,db len)
{
    vec v = l.v; v=v*(1.0/dis(v));
    v=vec(-v.y,v.x); v = v*len;
    line tmp = l; tmp.p = tmp.p+v;
    return tmp;
}
db solve()
{
    db lf = 0, rt = 1e4, mid, ans=0.0; int tms = 60;
    while(tms--)
    {
        mid = (lf+rt)/2.0;// printf("%lf %lf\n",lf,rt);
        for(int i=1;i<=n;i++)    l[i] = movein(r[i],mid);
        //if(abs(mid-5000)<eps)    for(int i=1;i<=n;i++)    putl(l[i]);
        //else    azy = 0;
        if(halfplane())    ans = mid, lf = mid+eps;
        else    rt = mid-eps;
    }
    return ans;
}
bool cmp(line a,line b)
{
    return a.ang<b.ang || (abs(a.ang-b.ang)<eps && cross(a.v,b.v)<eps);
}
int main()
{
    while(scanf("%d",&n))
    {
        if(!n)    break;
        for(int i=1;i<=n;i++)    scanf("%lf%lf",&pt[i].x,&pt[i].y);
        for(int i=1;i<=n;i++)    r[i] = line(pt[i],pt[i+1>n?1:i+1]);
        sort(r+1,r+n+1,cmp); //for(int i=1;i<=n;i++)    putl(r[i]);
        printf("%lf\n",solve());
    }
    return 0;
}
View Code

 

标签:return,Point,db,cross,Most,Distant,vec,poi,line
来源: https://www.cnblogs.com/hanyuweining/p/10360028.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有