ZOJ3663_Polaris of Pandora 2012 ICPC Changchun Site I 题
先是用经纬度算,调了很久,实在不会如何用经纬度求交点,百度谷歌也找不到。用三分法求了交点,有问题。。。
不得已各种三角函数反三角函数坐标旋转神马的都用上了,硬是求出三维坐标系的各种点再算,精度都不知损到哪里去了,竟然能AC了。。。
1、算临界线的纬度
2、判断行程所在平面的“斜率”是否能与临界线相交,不相交则100.000
3、把行程平面的x方向旋转到x轴正方向算出与临界线交点,再在临界面旋转到行程面与临界面交点
4、用球面距离和z坐标结合判断计算区间。
1 #include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 #include<math.h> 5 #include<vector> 6 #include<list> 7 #include<algorithm> 8 #include<iostream> 9 using namespace std; 10 const double eps = 1e-8; 11 const double pi = acos(-1.0); 12 inline int dcmp(double x){return (x > eps) - (x < -eps);} 13 inline double pz(double x) {return dcmp(x) ? x : 0;} 14 inline double Sqr(double x) {return x * x;} 15 inline double pcs(double x) {return x > 1 ? 1 : (x < -1 ? -1 : x);} 16 struct Point3 17 { 18 double x, y, z; 19 Point3(){x = y = z = 0;} 20 Point3(double a, double b, double c){x = a, y = b, z = c;} 21 Point3 cross(Point3 p){return 22 Point3(y * p.z - p.y * z, z * p.x - x * p.z, x * p.y - y * p.x);} 23 double dot(Point3 p){return x * p.x + y * p.y + z * p.z;} 24 Point3 operator-(const Point3 &p)const{return Point3(x - p.x, y - p.y, z - p.z);} 25 Point3 operator-()const{return Point3(-x, -y, -z);} 26 Point3 operator+(const Point3 &p)const{return Point3(x + p.x, y + p.y, z + p.z);} 27 Point3 operator*(const double &b)const{return Point3(x * b, y * b, z * b);} 28 Point3 operator/(const double &b)const{return Point3(x / b, y / b, z / b);} 29 Point3 fxl(Point3 b, Point3 c){return (*this - b).cross(b - c);} 30 double Dis(Point3 b){return sqrt((*this - b).dot(*this - b));} 31 double Rdis(Point3 b, double R){return R * asin(pcs((*this).Dis(b) * 0.5 / R)) * 2;} 32 double vlen(){return sqrt(dot(*this));} 33 Point3 RotePoint(const Point3 &p, double ang) 34 { 35 return Point3((p.x - x) * cos(ang) - (p.y - y) * sin(ang) + x, 36 (p.x - x) * sin(ang) + (p.y - y) * cos(ang) + y, p.z); 37 } 38 }; 39 double R, H, lat1, lng1, lat2, lng2, lat; 40 inline double p2cross(const Point3 &a, const Point3 &b, const Point3 &c) 41 {return (b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y);} 42 Point3 r(0, 0, 0); 43 int main() 44 { 45 while(scanf("%lf%lf%lf%lf%lf%lf", &R, &H, &lat1, &lng1, &lat2, &lng2) != EOF) 46 { 47 double R_ = R; lat = acos(R / (R + H)); R += H; 48 lat1 += pi * 0.5, lat2 += pi * 0.5; 49 Point3 s(R * sin(lat1) * cos(lng1), R * sin(lat1) * sin(lng1), R * cos(lat1)); 50 Point3 e(R * sin(lat2) * cos(lng2), R * sin(lat2) * sin(lng2), R * cos(lat2)); 51 Point3 f = r.fxl(s, e); 52 double as = asin(pcs(fabs(f.cross(Point3(0, 0, 100)).vlen() / f.vlen() / 100))); 53 if(as < lat + eps) {printf("100.000\n"); continue;} 54 double len = R * sin(lat) / tan(as); 55 Point3 jd1(len, sqrt(Sqr(R_) - Sqr(len)), -R * sin(lat)); 56 Point3 jd2(len, -sqrt(Sqr(R_) - Sqr(len)), -R * sin(lat)); 57 if(f.z < -eps) f = -f; 58 double ang = atan2(f.y, f.x); 59 jd1 = r.RotePoint(jd1, ang), jd2 = r.RotePoint(jd2, ang); 60 double s1d = s.Rdis(jd1, R), s2d = s.Rdis(jd2, R); 61 double e1d = e.Rdis(jd1, R), e2d = e.Rdis(jd2, R); 62 double sed = s.Rdis(e, R), jd = jd1.Rdis(jd2, R); 63 if(!dcmp(s1d + e1d - sed) && !dcmp(s2d + e2d - sed)) 64 printf("%.3f\n", (sed - jd) / sed * 100); 65 else if(!dcmp(s1d + e1d - sed)) 66 { 67 if(e.z < s.z) printf("%.3f\n", s1d / sed * 100); 68 else printf("%.3f\n", e1d / sed * 100); 69 } 70 else if(!dcmp(s2d + e2d - sed)) 71 { 72 if(e.z < s.z) printf("%.3f\n", s2d / sed * 100); 73 else printf("%.3f\n", e2d / sed * 100); 74 } 75 else printf(e.z < jd1.z ? "0.000\n" : "100.000\n"); 76 } 77 return 0; 78 }