题意 : 给你一个点和一个圆形和一个矩形,让你求这个点先到矩形,再到圆形折线的最小值。
题解 : 我们发现,对于圆上的任意一个点我们都可以求出这个点到这个矩形的最小距离,然后我们就可以通过三分圆上的点找到这个最优解就可以了
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
const double PI = 3.141592653589793;
const double eps = 1e-8;
const double INF = 1e30;
struct point {
double x,y;
};
struct circle {
point o;
double r;
};
struct rec {
point a,b,c,d;
};
circle c;
point p;
rec fx;
int sgn (double x) {
if (fabs (x) <= eps) return 0;
return x > 0 ? 1 : -1;
}
double dist (point a,point b) {
return sqrt ((a.x - b.x) * (a.x - b.x ) + (a.y - b.y ) * (a.y - b.y));
}
double cross (point a,point b,point c) {
return (b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y);
}
double dot (point a,point b,point c) {
return (b.x - a.x) * (c.x - a.x) + (b.y - a.y) * (c.y - a.y );
}
double dis (point a,point b,point c) {
if (sgn (dist (a,b)) == 0) return dist (a,c);
if (dot (a,b,c) < 0) return dist (a,c);
if (dot (b,a,c) < 0) return dist (b,c);
double area = fabs (cross (a,b,c));
return area / dist (a,b);
}
double f (double ang) {
point temp = c.o;
temp.x += cos (ang) * c.r;
temp.y += sin (ang) * c.r;
double res = dist (temp,p);
// printf ("%.3f ",res);
double rr = INF;
rr = min (rr,dis (fx.a,fx.b,temp));
rr = min (rr,dis (fx.b,fx.c,temp));
rr = min (rr,dis (fx.c,fx.d,temp));
rr = min (rr,dis (fx.d,fx.a,temp));
res += rr;
// printf ("%.3f\n",res);
return res;
}
double solve () {
double l = 0,r = PI;
double res = INF;
while (r - l > eps) {
double mid = (l + l + r) / 3;
double midd = (l + r + r) / 3;
if (f(mid) > f(midd)) {
l = mid;
res = min (res,f (midd));
}
else {
r = midd;
res = min (res,f (mid));
}
}
l = PI,r = 2 * PI;
while (r - l > eps) {
double mid = (l + l + r) / 3;
double midd = (l + r + r) / 3;
if (f(mid) > f(midd)) {
l = mid;
res = min (res,f (midd));
}
else {
r = midd;
res = min (res,f (mid));
}
}
return res;
}
int main () {
double x,y;
while(scanf ("%lf%lf",&x,&y) && (sgn(x) || sgn(y))) {
p.x = x,p.y = y;
scanf ("%lf%lf%lf",&c.o.x,&c.o.y,&c.r);
scanf ("%lf%lf%lf%lf",&fx.a.x,&fx.a.y,&fx.c.x,&fx.c.y);
fx.b.x = fx.a.x,fx.b.y = fx.c.y;
fx.d.x = fx.c.x,fx.d.y = fx.a.y;
// printf ("%.3f %.3f\n",fx.b.x,fx.b.y);
double ans = solve ();
printf ("%.2f\n",ans);
}
return 0;
}