计蒜客A1484 Tunnelling the Earth

75 篇文章 0 订阅

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 92935219293521 metres following the great circle route around the earth, but only 84911888491188 metres following the straight line through the earth.

For this problem, assume that the earth is a perfect sphere with radius of 63710096371009 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.

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.

样例输入复制
1
43.466667 -80.516667 30.058056 31.228889
样例输出复制
802333
题目来源
10 July, 2010 - Waterloo local contest

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>

using namespace std;

const long long R = 6371009;
const double Pai = acos(-1);

inline double Midify(double x) { return x * Pai / 180.0; }

inline double calc1(double x) {
    // 我用的是解三角形公式    其实网上有一种根据两点经纬度计算两点之间球面距离的公式  但是比较那啥...  我也没看懂
    return R * acos((R * R * 2 - x * x ) / (2 * R * R)
            );
}

inline double calc2(double x,double y,double a,double b) {
    // 拆解三维坐标  求两点之间的距离
    // 下午比赛的时候我居然傻*到企图拆解成二维的
    double x1 = R * cos(y) * cos(x),y1 = R * cos(y) * sin(x),z1 = R * sin(y);
    double x2 = R * cos(b) * cos(a),y2 = R * cos(b) * sin(a),z2 = R * sin(b);
    return pow(x1 - x2,2) + pow(y1 - y2,2) + pow(z1 - z2,2);
}

int main(int argc,char *argv[]) {
    int T; scanf("%d",&T);
    double x,y,a,b;
    while(T--) {
        scanf("%lf %lf %lf %lf",&y,&x,&b,&a); // y b --纬度
        x = Midify(x);
        y = Midify(y);
        a = Midify(a);
        b = Midify(b);
        double dist = sqrt( calc2(x,y,a,b) );
        printf("%d\n",int(calc1(dist) - dist + 0.5));
    }


    return 0;
}

附上网上的一种做法
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

七情六欲·

学生党不容易~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值