POJ 3525 Most Distant Point from the Sea

来源:互联网 发布:日向日足 知乎 编辑:程序博客网 时间:2024/06/01 18:28

这道题关键点就在于线段的平移,把线段向着其半平面方向移动r的距离,具体做法风注释

再说说一直错的点,刚开始把点方向规整化的部分写在循环里了,导致这部分一直在执行,实际上只执行一次就可以了。。

#include<stdio.h>#include<math.h>#include<algorithm>using namespace std;const double eps=1e-6;struct Point {    double x,y;    Point (){};    Point (double xx,double yy) {x=xx;y=yy;}    Point operator -(const Point &b)const {        return Point(x-b.x,y-b.y);    }    double operator ^(const Point &b)const{        return x*b.y-y*b.x;    }};struct Line {    Point s,e;    double angle;    Line(){};    Line(Point ss,Point ee){s=ss;e=ee;}    Point operator &(const Line b) {        Point res=s;        double t=((s-b.e)^(b.s-b.e))/((s-e)^(b.s-b.e));        res.x+=(e.x-s.x)*t;        res.y+=(e.y-s.y)*t;        return res;    }};int n,m;Point p[105];Line l[105],dq[105];void init(double r) {    for(int i=0;i<n;i++) {        //把点进行偏移后把点加入线段中        double dy,dx,len;        Point ta,tb;        dx=p[i+1].y-p[i].y;        dy=p[i].x-p[i+1].x;        len=sqrt(dx*dx+dy*dy);        ta.x=p[i].x+dx*r/len;        ta.y=p[i].y+dy*r/len;        tb.x=p[i+1].x+dx*r/len;        tb.y=p[i+1].y+dy*r/len;        l[i].s=ta;    l[i].e=tb;        l[i].angle=atan2(l[i].e.y-l[i].s.y,l[i].e.x-l[i].s.x);    }}int cmp(Line a,Line b) {    if (fabs(a.angle-b.angle)<eps) return ((a.e-a.s)^(b.s-a.s))>eps;//即b在a的左方,留下a    else return a.angle<b.angle;}int EqualPoint(Point a,Point b) {    return b.x-a.x==0 && b.y-a.y==0;}int HPI(double r) {    init(r);    sort(l,l+n,cmp);    int ln;    for(int i=1,j=0;i<n;i++) {        if (l[i].angle-l[j].angle>eps) l[++j]=l[i];        ln=j+1;    }    dq[0]=l[0]; dq[1]=l[1];    int bot=0,top=1;    for(int i=2;i<ln;i++) {        while (bot<top && ((l[i].e-l[i].s)^((dq[top]&dq[top-1])-l[i].s))>eps) top--;        while (bot<top && ((l[i].e-l[i].s)^((dq[bot]&dq[bot+1])-l[i].s))>eps) bot++;        dq[++top]=l[i];    }    while (bot<top && ((dq[bot].e-dq[bot].s)^((dq[top]&dq[top-1])-dq[bot].s))>eps) top--;    while (bot<top && ((dq[top].e-dq[top].s)^((dq[bot]&dq[bot+1])-dq[top].s))>eps) bot++;    if (top<=bot+1) return 0;    else return 1;    m=0;    dq[++top]=dq[bot];    for(int i=bot;i<top;i++) {        p[m++]=dq[i]&dq[i+1];    }    m=unique(p,p+m,EqualPoint)-p;    if(m>0) return 1;    else return 0;}int main() {    #ifndef ONLINE_JUDGE    freopen("in.txt","r",stdin);    #endif // ONLINE_JUDGE    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/2;i++) swap(p[i],p[n-1-i]);//把点变成顺时针的        //for(int i=0;i<n;i++) printf("%.2lf  %.2lf\n",p[i].x,p[i].y);        p[n]=p[0];        double high=20000,low=0;        double mid;        while(low+eps<=high) {            mid=(high+low)/2.0;            if (HPI(mid)) low=mid;            else high=mid;//没有交点则说明mid过大        }        printf("%f\n",high);    }    return 0;}


0 0
原创粉丝点击