Blizzard(暴力技巧+精度问题)
Blizzard
Description
在魔兽争霸之冰封王座中有一个叫冰川的地图,里面有魔法传送阵,可以传送到这个此传送阵的对称传送阵位置。假设地图是圆形的,地图中心也就是圆心,在圆上每个点都有一个传送阵,可以传送到与地图圆心中心对称的位置。现在因为贪婪的大魔法师,人族正经历一场浩劫,作为聪明的兽族先知,信奉趁你病要你命的原则,想要趁机占领人族的土地。你能计算最短距离能够使兽族大军尽快到达人族营地?
Input
第一行一个整数r(1 <= r <= 1000)代表地图的半径。接下来两行两个整数分别代表兽族出发点的位置和人族营地的位置坐标。保证两个位置都在圆内(可能在边界上),地图中心在点(0, 0)上。
Output
输出一个实数,代表兽族大军最短需要移动多少距离。和答案相对或绝对相差1e-6都算正确。
Sample Input 1
1
0 1
0 -1
Sample Output 1
0.000000000000
Sample Input 2
4
3 0
-3 0
Sample Output 2
2.000000000000
Hint:
第二个样例抽象图
1 #include<iostream>
2 #include<cstdio>
3 #include<cmath>
4 #include<cstring>
5 #include<algorithm>
6 #define Min(a,b) a<b?a:b
7 #define eps 1e-4
8 #define pi 3.1415926
9 using namespace std;
10
11 double ans;
12 double dis(double x0,double y0,double x1,double y1)
13 {
14 return sqrt(pow((x1-x0),2)+pow((y1-y0),2));
15 }
16 int main()
17 {
18 double r,x1,x2,y1,y2;
19 scanf("%lf%lf%lf%lf%lf",&r,&x1,&y1,&x2,&y2);
20 /* if(abs(y1-y2)/abs(x1-x2)==1)
21 {
22 ans=2*r-(sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)));
23 }
24 else
25 {*/ //不能写if 因为存在两点重合的情况
26 ans=dis(x1,y1,x2,y2);
27 for(double i=0;i<=360;i+=eps)
28 {
29 ans=Min(ans,(dis(x1,y1,r*cos(i/180*pi),r*sin(i/180*pi))+dis(x2,y2,-r*cos(i/180*pi),-r*sin(i/180*pi))));
30 }//圆上坐标表示为(R*cos,R*sin);
31 //}
32 printf("%.8lf\n",ans);
33 return 0;
34 }