这题一开始就想到的是三分法,不过太菜了写不来。。。只能暴力了精度要求较低0.01即可。由于以前计算几何的题目几乎没写过几道,于是写的时候各种代码不规范WA了几次。也难怪这次在成都F出现问题导致最终没拿到牌。
要注意的是如何求一点到正方形的距离,一开始我套了模版求点到四条边的最短距离的最小值,果断超时了0.0
最后还是上网看了一下(数学太渣不擅长推公式只能上网看)发现了一个较为简便的方法,最终AC了。
代码如下:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <cstdlib> 6 #define INF 0x7fffffff 7 #define pi acos(-1.0) 8 using namespace std; 9 10 typedef struct{ 11 double x, y; 12 }Point; 13 14 Point st, circle, Reca, Recb, locP; 15 16 inline double dist(Point a, Point b) 17 { 18 return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); 19 } 20 21 double PtoRECT(Point pos, Point ra, Point rb) 22 { 23 double x=0,y=0; 24 if(pos.x<ra.x) x=ra.x-pos.x; 25 else if(pos.x>rb.x) x=pos.x-rb.x; 26 if(pos.y<ra.y) y=ra.y-pos.y; 27 else if(pos.y>rb.y) y=pos.y-rb.y; 28 return sqrt(x*x+y*y); 29 30 } 31 32 int main() 33 { 34 // freopen("in.txt", "r", stdin); 35 36 double r; 37 while(scanf("%lf%lf", &st.x, &st.y)!=EOF){ 38 if(st.x==0 && st.y==0) break; 39 scanf("%lf%lf%lf", &circle.x, &circle.y, &r); 40 scanf("%lf%lf", &Reca.x, &Reca.y); 41 scanf("%lf%lf", &Recb.x, &Recb.y); 42 if(Reca.x>Recb.x) swap(Reca.x, Recb.x); 43 if(Reca.y>Recb.y) swap(Reca.y, Recb.y); 44 double ans = INF; 45 for(double dre=0; dre<=360; dre+=0.01){ //枚举角度 46 locP.x = circle.x+cos(dre/180*pi)*r; 47 locP.y = circle.y+sin(dre/180*pi)*r; 48 ans = min(ans, PtoRECT(locP, Reca, Recb)+dist(locP,st)); 49 } 50 printf("%.2lf ", ans); 51 } 52 return 0; 53 }