HDU4454(暴力枚举)

这题一开始就想到的是三分法,不过太菜了写不来。。。只能暴力了精度要求较低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 }
View Code
奔跑吧!少年!趁着你还年轻
原文地址:https://www.cnblogs.com/shu-xiaohao/p/3385065.html