POJ3525 Most Distant Point from the Sea

半平面交+二分

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

然后注意精度问题 【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

 

posted @ 2019-02-10 19:21  寒雨微凝  阅读(143)  评论(0编辑  收藏  举报