题目大意:
假设地球是一个球体,给出起点的经纬度A(x1,y1),A(x1,y1), 终点的经纬度B(x2,y2)B(x2,y2)。
x:x: 纬度,北纬为正,南纬为负;
y:y: 经度,东经为正,西经为负。
令:
D1D1为两点的距离;
D2D2为起点AA先沿着纬线,再沿着经线 走到终点BB的距离。
求D1,D2求D1,D2。
数据范围:
1≤T≤100001≤T≤10000
|x1|,|x2|≤90,|y1|,|y2|≤180|x1|,|x2|≤90,|y1|,|y2|≤180
解题思路:
这道题不重要,重要的是怎么求地球上两点的距离。
图的话,将就看这个吧!懒得画了,,,只看图就好,,,
球面坐标和直角坐标存在一一对应的关系:球面有一点M(r,φ,θ)M(r,φ,θ),
则,点MM的直角坐标和球面坐标的关系为:
⎧⎩⎨x=rcosφcosθy=rcosφsinθz=rsinφ
{x=rcosφcosθy=rcosφsinθz=rsinφ
设A(r,α,β),B(r,φ,θ)设A(r,α,β),B(r,φ,θ),
则有OA→=(rcosαcosβ,rcosαsinβ,rsinα),OB→=(rcosφcosθ,rcosφsinθ,rsinφ)则有OA→=(rcosαcosβ,rcosαsinβ,rsinα),OB→=(rcosφcosθ,rcosφsinθ,rsinφ)
由此可得,夹角ang=arccos(OA→⋅OB→|OA→|⋅|OB→|)ang=arccos(OA→⋅OB→|OA→|⋅|OB→|)
化简得:ang=arccos(cosαcosφcos(β−θ)+sinαsinφ)ang=arccos(cosαcosφcos(β−θ)+sinαsinφ)
夹角出来了,距离就好办了。
距离的问题解决了,其他都不重要了。不对,这道题还没完呢!,,,
有一个坑点:当一个点在东半球,另一个在西半球时,需要特别注意一下角度,稍微想想。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 1000000000;
const int maxn = 100;
const double R=6371.0;
int main()
{
int t;
double dd;
double wa,wb,ja,jb;
cin>>t;
while(t--)
{
scanf("%lf%lf%lf%lf",&wa,&ja,&wb,&jb);
if(abs(ja-jb)>180.0)
{
if(ja<0.0)
ja+=360.0;
else if(jb<0.0)
jb+=360.0;
}
dd=R*acos(sin(wa/180.0*PI)*sin(wb/180.0*PI)+cos(wa/180.0*PI)*cos(wb/180.0*PI)*cos((ja-jb)/180.0*PI));
printf("%.10lf ",dd);
double wc=wa;
double jc=jb;
double d1=R*acos(sin(wb/180.0*PI)*sin(wc/180.0*PI)+cos(wb/180.0*PI)*cos(wc/180.0*PI)*cos((jb-jc)/180.0*PI));
double r=R*cos(wa/180.0*PI);
double d2=(abs(ja-jc)/180.0*PI)*r;
printf("%.10lf\n",d1+d2);
}
return 0;
}