HDU 4454

我比较快速的想到了三分,但是我是从0到2*pi区间进行三分,并且漏了一种点到边距离的情况,一直WA了好几次

后来画了下图才发现,0到2*pi区间内是有两个极值的,每个半圆存在一个极值

以下是代码

#include <cstdio>
#include <cmath>
#include <algorithm>
#define pi acos(-1.0)
using namespace std;

typedef struct
{
    double x;
    double y;
}point;

typedef struct
{
    double x;
    double y;
    double r;
}circle;

typedef struct
{
    point s;
    point e;
}line;


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 cal(point st,line ed,circle c,double t)
{
    point p;
    p.x=c.x+cos(t)*c.r;
    p.y=c.y+sin(t)*c.r;
    if(fabs(ed.s.x-ed.e.x)<1e-8)
    {
        if(p.y>ed.s.y&&p.y<ed.e.y)
        {
            return dis(p,st)+fabs(p.x-ed.s.x);
        }
        else
        {
            double t=min(dis(p,ed.s),dis(p,ed.e));
            return dis(p,st)+t;
        }

    }
    if(fabs(ed.s.y-ed.e.y)<1e-8)
    {
        if(p.x>ed.s.x&&p.x<ed.e.x)
        {
            return dis(p,st)+fabs(p.y-ed.s.y);
        }
        else
        {
            double t=min(dis(p,ed.s),dis(p,ed.e));
            return dis(p,st)+t;
        }
    }
    return -1;
}

double solve1(point st,line ed,circle c)
{
    double L=0,R=pi,mid=(L+R)/2,midmid=(mid+R)/2;
    while(R-L>1e-10)
    {
        if(cal(st,ed,c,mid)<cal(st,ed,c,midmid))R=midmid;
        else L=mid;
        mid=(L+R)/2;
        midmid=(R+mid)/2;
    }
    return cal(st,ed,c,midmid);
}

double solve2(point st,line ed,circle c)
{
    double L=pi,R=2*pi,mid=(L+R)/2,midmid=(mid+R)/2;
    while(R-L>1e-10)
    {
        if(cal(st,ed,c,mid)<cal(st,ed,c,midmid))R=midmid;
        else L=mid;
        mid=(L+R)/2;
        midmid=(R+mid)/2;
    }
    return cal(st,ed,c,midmid);
}

int main()
{
    double m,x[2],y[2];
    point st;
    circle cir;
    line a[4];
    while(scanf("%lf%lf",&st.x,&st.y)==2)
    {
        if(!st.x&&!st.y)break;
        scanf("%lf%lf%lf",&cir.x,&cir.y,&cir.r);
        scanf("%lf%lf",&x[0],&y[0]);
        scanf("%lf%lf",&x[1],&y[1]);
        if(x[0]>x[1]) swap(x[0],x[1]);
        if(y[0]>y[1]) swap(y[0],y[1]);
        a[0].s.x=x[0];a[0].s.y=y[0];
        a[0].e.x=x[0];a[0].e.y=y[1];
        a[1].s.x=x[0];a[1].s.y=y[0];
        a[1].e.x=x[1];a[1].e.y=y[0];
        a[2].s.x=x[1];a[2].s.y=y[0];
        a[2].e.x=x[1];a[2].e.y=y[1];
        a[3].s.x=x[0];a[3].s.y=y[1];
        a[3].e.x=x[1];a[3].e.y=y[1];
        m=1e18;
        for(int i=0;i<4;i++)
        {
            double t=solve1(st,a[i],cir);
            if(t<m)m=t;
            t=solve2(st,a[i],cir);
            if(t<m)m=t;
        }
        printf("%.2lf
",m);
    }
    return 0;
}


原文地址:https://www.cnblogs.com/riskyer/p/3297356.html