Description
Problem E: Tunnelling the Earth
There are different methods of transporting people from place to place: cars, bikes, boats, trains, planes, etc. For very long distances, people generally fly in a plane. But this has the disadvantage that the plane must fly around the curved surface of the earth. A distance travelled would be shorter if the traveller followed a straight line from one point to the other through a tunnel through the earth.For example, travelling from Waterloo to Cairo requires a distance of 9293521 metres following the great circle route around the earth, but only 8491188 metres following the straight line through the earth.
For this problem, assume that the earth is a perfect sphere with radius of 6371009 metres.
Input Specification
The first line of input contains a single integer, the number of test cases to follow. Each test case is one line containing four floating point numbers: the latitude and longitude of the origin of the trip, followed by the latitude and longitude of the destination of the trip. All of these measurements are in degrees. Positive numbers indicate North latitude and East longitude, while negative numbers indicate South latitude and West longitude.Sample Input
1 43.466667 -80.516667 30.058056 31.228889
Output Specification
For each test case, output a line containing a single integer, the difference in the distance between the two points following the great circle route around the surface of the earth and following the straight line through the earth, in metres. Round the difference of the distances to the nearest integer number of metres.Output for Sample Input
802333
题意:
给出球面上,两个点的经度和纬度。求出两点的球面距离和直线距离。
思路:
先将角度化为弧度,求出两点的三维坐标。然后根据公式即可得到距离。
CODE:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <string>
#include <cstring>
#include <queue>
#include <stack>
#include <vector>
#include <set>
#include <map>
const int inf=0xfffffff;
typedef long long ll;
using namespace std;
const double PI = acos(-1.0);
const double R = 6371009;
double a, b, c, d;
struct node
{
double x, y, z;
node(double x = 0, double y = 0, double z = 0):x(x), y(y), z(z){}
};
typedef node vec;
vec operator -(vec A,vec B){return vec(A.x-B.x,A.y-B.y,A.z-B.z);}
double dot(vec A, vec B){return A.x * B.x + A.y * B.y + A.z * B.z;}
double length(vec A){return sqrt(dot(A, A));}
double ch(double n)
{
return n / 180.0 * PI;
}
node get_point(double a, double b)
{
node p;
p.x = R * cos(a) * cos(b);
p.y = R * cos(a) * sin(b);
p.z = R * sin(a);
return p;
}
int main()
{
//freopen("in", "r", stdin);
int T;
scanf("%d", &T);
while(T --){
scanf("%lf %lf %lf %lf", &a, &b, &c, &d);
a = ch(a); b = ch(b); c = ch(c); d = ch(d);
vec C, D;
double ans1, ans2;
C = get_point(a, b);
D = get_point(c, d);
ans1 = length(C - D);
ans2 = asin(ans1 / (2.0 * R)) * 2 * R;
printf("%d\n", (int)(ans2 - ans1 + 0.5));
}
return 0;
}