New Game!
描述
题目描述:
Eagle Jump公司正在开发一款新的游戏。泷本一二三作为其员工,获得了提前试玩的机会。现在她正在试图通过一个迷宫。
这个迷宫有一些特点。为了方便描述,我们对这个迷宫建立平面直角坐标系。迷宫中有两条平行直线 L1:Ax+By+C1=0, L2:Ax+By+C2=0,
还有 n个圆 Ci:(x−xi)^2+(y−yi)^2=ri^2。角色在直线上、圆上、圆内行走不消耗体力。在其他位置上由S点走到T点消耗的体力为S和T的欧几里得距离。
泷本一二三想从 L1 出发,走到L2 。请计算最少需要多少体力。
输入:
第一行五个正整数 n,A,B,C1,C2 (1≤n≤1000,−10000≤A,B,C1,C2≤10000),其中 A,B不同时为 0。
接下来 n 行每行三个整数 x,y,r(−10000≤x,y≤10000,1≤r≤10000) 表示一个圆心为 (x,y),半径为 r 的圆。
输出:
仅一行一个实数表示答案。与标准答案的绝对误差或者相对误差不超过10^−4 即算正确。
样例输入
2 0 1 0 -4
0 1 1
1 3 1
样例输出
0.236068
由于圆是没有消耗的,所以可以将每个圆都坍缩成点,然后求L1到L2的最短路即可。
1 #include<math.h> 2 #include<stdio.h> 3 #define MAXN 1000 4 struct point 5 { 6 double x,y; 7 }; 8 struct line 9 { 10 point a,b; 11 }; 12 13 double distance(point p1,point p2) 14 { 15 return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)); 16 } 17 double disptoline(point p1,double a,double b,double c) 18 { 19 double x=sqrt(a*a+b*b); 20 return fabs((a*p1.x+b*p1.y+c)/x); 21 } 22 23 point pp[1005]; 24 double r[1005]; 25 double e[1005][1005],d[1005]; 26 int used[1005]; 27 double inf=1e9; 28 void dij(int s,int n) 29 { int v,u,max=0; 30 31 for(u=0;u<=n;u++) 32 d[u]=inf,used[u]=0; 33 34 d[s]=0; 35 36 37 while(1) 38 { v=-1; 39 for(u=0;u<=n;u++) 40 { if(!used[u]&&(v==-1||d[u]<d[v])) 41 v=u; 42 43 } 44 if(v==-1) break; 45 used[v]=1; 46 47 for(u=0;u<=n;u++) 48 if(d[u]>d[v]+e[v][u]) 49 d[u]=d[v]+e[v][u]; 50 } 51 } 52 53 int main() 54 { 55 int n; 56 double a,b,c1,c2; 57 scanf("%d",&n); 58 scanf("%lf%lf%lf%lf",&a,&b,&c1,&c2); 59 for(int i=0;i<=n+1;i++) 60 { 61 for(int j=0;j<=n+1;j++) 62 e[i][j]=inf; 63 } 64 for(int i=1;i<=n;i++) 65 { 66 scanf("%lf%lf%lf",&pp[i].x,&pp[i].y,&r[i]); 67 } 68 69 for(int i=1;i<=n;i++) 70 { 71 double lt=disptoline(pp[i],a,b,c1); 72 73 if(lt<r[i]) e[0][i]=0; 74 else e[0][i]=lt-r[i]; 75 } 76 for(int i=1;i<=n;i++) 77 { 78 double lt=disptoline(pp[i],a,b,c2); 79 if(lt<r[i]) e[i][n+1]=0; 80 else e[i][n+1]=lt-r[i]; 81 } 82 for(int i=1;i<=n;i++) 83 for(int j=1;j<=n;j++) 84 { if(i==j) continue; 85 double lt=distance(pp[i],pp[j]); 86 if(lt>r[i]+r[j]) e[i][j]=lt-r[i]-r[j]; 87 else e[i][j]=0; 88 } 89 point t; 90 t.y=1.0,t.x=-(b*1.0+c1)/a; 91 e[0][n+1]=disptoline(t,a,b,c2); 92 dij(0,n+1); 93 94 printf("%.10f ",d[n+1]); 95 return 0; 96 }