POJ 3384 Feng Shui

来源:互联网 发布:淘宝虚假交易如何挽救 编辑:程序博客网 时间:2024/05/17 07:46

坑爹的题,,就是先向内推进r,然后半平面交得出圆心范围。

然后旋转卡壳求最远点对

这道题首先样例给的就不对,不知道什么情况

然后一直WA,后来看了discuss,试了下这组数据:

4 1
0 0
0 2
2 2
2 0

发现n个端点两两距离都一样时会出错,然后改了改代码,就A了

总结就是一直WA的时候,一定要学会看discuss

#include<stdio.h>#include<algorithm>#include<math.h>using namespace std;const double eps=1e-5;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)const {        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;int r;Point p[105];Line l[105],dq[105];int cmp(Line a,Line b) {    if (fabs(a.angle-b.angle)<eps) return ((a.e-a.s)^(b.s-a.s))>eps;    else return a.angle<b.angle;}double dist(Point a,Point b) {    return sqrt((b.x-a.x)*(b.x-a.x)+(b.y-a.y)*(b.y-a.y));}void HPI(){    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=0;i<ln;i++) printf("%f %f\n",l[i].s.x,l[i].s.y);    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++;    //for(int i=bot;i<top;i++) printf("%lf %lf\n",dq[i].s.x,dq[i].s.y);    if (top<=bot+1) return;    dq[++top]=dq[bot];    m=0;    for(int i=bot;i<top;i++){        p[m++]=dq[i]&dq[i+1];        //printf("%lf %lf\n",p[m-1].x,p[m-1].y);    }    //方便处理    p[m]=p[0];}int main() {    #ifndef ONLINE_JUDGE    freopen("in.txt","r",stdin);    #endif // ONLINE_JUDGE    while(scanf("%d%d",&n,&r)!=EOF) {        for(int i=0;i<n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);        p[n]=p[0];        for(int i=0;i<n;i++) {            //向内推进r            double dx,dy,len;            Point ta,tb;            ta=p[i];tb=p[i+1];            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(tb.y-ta.y,tb.x-ta.x);            //printf("%f %f\n",l[i].s.x,l[i].s.y);        }        HPI();        //旋转卡壳求最远点对,点逆时针排列        double ans=0;        Point a,b;        //printf("%d\n",m);        for(int i=0,j=1;i<m;i++) {            while(((p[i+1]-p[i])^(p[j]-p[i]))<((p[i+1]-p[i])^(p[j+1]-p[i]))) j=(j+1)%m;            //printf("%f \n",((p[i+1]-p[i])^(p[j]-p[i])));            //printf("%f %f\n",p[i].x,p[i].y);            if (dist(p[i],p[j])>=ans) {                a=p[i];b=p[j];                ans=dist(p[i],p[j]);            }            if (dist(p[i+1],p[j+1])>=ans) {                a=p[i+1];b=p[j+1];                ans=dist(p[i+1],p[j+1]);            }        }        printf("%.4f %.4f %.4f %.4f\n",a.x,a.y,b.x,b.y);    }    return 0;}


0 0
原创粉丝点击