hdu 4454(三分)


三分有两种写法,一种是平均三分,在区间里分成三等分。
另一种是取中点,再取中点与右端点的中点进行三分。
在这题里,第一种可以过,第二种不能过。


所以以后还是都用平均的三分板子吧

#include<bits/stdc++.h>
using namespace std;
#define clr(x,y) memset(x,y,sizeof x)

const int maxn = 10 + 10;
struct Node{double x,y;};
#define PI acos(-1.0)
#define eps 1e-8

Node p,pr,p1,p2;
double rr;

double dis(Node p1,Node p2)
{
    return sqrt( (p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
}
double get1(double x)
{
    double t = sqrt(rr * rr - (x - pr.x) * (x - pr.x));
    double t1 = t + rr,t2 = rr - t;
    return t1;
}
double get2(double x)
{
    double t = sqrt(rr * rr - (x - pr.x) * (x - pr.x));
    double t1 = t + rr,t2 = rr - t;
    return t2;
}
double L,R,High,Low,l,r,high,low;

double fun(double angle)
{
    double ret = 1e18;
    double x = pr.x + rr * cos(angle),y = pr.y + rr * sin(angle);
    ret = min(ret,dis((Node){x,y},(Node){l,low}));
    ret = min(ret,dis((Node){x,y},(Node){l,high}));
    ret = min(ret,dis((Node){x,y},(Node){r,low}));
    ret = min(ret,dis((Node){x,y},(Node){r,high}));

    if(x >= l && x <= r)ret = min(ret,fabs(y - high)),ret = min(ret,fabs(y - low));
    if(y >= low && y <= high)ret = min(ret,fabs(x - l)),ret = min(ret,fabs(x - r));
    return ret + dis((Node){x,y},p);
}
int main()
{

   while( ~ scanf("%lf%lf",&p.x,&p.y))
   {
       if(p.x == 0 && p.y == 0)break;
       scanf("%lf%lf%lf%lf%lf%lf%lf",&pr.x,&pr.y,&rr,&p1.x,&p1.y,&p2.x,&p2.y);
       l = p1.x,r = p2.x,low = p1.y,high = p2.y;
       if(l > r)swap(l,r);if(low > high)swap(low,high);

        L = pr.x - rr,R = pr.x + rr,Low = pr.y - rr,High = pr.y + rr;
        double LL = 0,RR = 2 * PI;
        double ans;
        while((RR - LL) > eps)
        {
//            cout << LL << " " << RR << endl;
            double t = (RR - LL)/3.0;
            double mid = LL + t,mmid = LL + 2 * t;
            if(fun(mid) < fun(mmid))
                ans = fun(mid),RR = mmid;
            else ans = fun(mmid),LL = mid;
        }
       printf("%.2f\n",ans);
   }
   return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值