三分有两种写法,一种是平均三分,在区间里分成三等分。
另一种是取中点,再取中点与右端点的中点进行三分。
在这题里,第一种可以过,第二种不能过。
所以以后还是都用平均的三分板子吧
#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;
}