TOJ-1344 Equidistance

Alice and Bob haven't met for some time. Bob isn't very happy about this, so he urges Alice to finally make time for a meeting. Let's listen to an extract from a phone call:

Alice: ... maybe we should meet on neutral territory.
Bob: I've already heard this from you --- two years ago.
Alice: I know ; I just haven't found yet a suitable place that is roughly at the same distance from both yours and mine.
Bob: Well, the geometric place of the points that are equidistant from two given points on the surface of a sphere (and the earth is a sphere rather than a disc) is a great circle (namely the one which intersects the great circle through the given points orthogonally at the center of them). If you insist only on approximately equal distances though, we get a zone of some kilometers width and about 40000 km length. Not everything in this zone is water. Thus I think it is a feasible task to find a fitting place.
Alice: Now, if I tell you to pick any, we'll certainly land up in Honolulu.
Bob: Which is not a too bad idea. So, may I pick any ?
Alice: As long as I don't have to accept --- but I'm open to suggestions.
Bob: Honolulu ?
Alice: Is it situated on aforementioned geometric place at all ??!
Bob: Not quite ...

Nice. Now let's stop the preliminaries and come to the facts: Given two locations on the earth's surface you can find the geometric place of all equidistant points on the surface. For another given location calculate its distance on the surface to this geometric place. Assume that the earth is a sphere with a radius of 6378 km.

Input Specification

The input file consists of two parts: a list of locations and a list of queries.

The location list consists of up to 100 lines, one line per location. Each contains a string and two floating-point numbers, separated by whitespace, representing the name of the location, its latitude and its longitude. Names are unique and shorter than 30 characters and do not contain whitespace. Latitudes are between -90 (South Pole) and 90 (North Pole) inclusive. Longitudes are between -180 and 180 inclusive where negative numbers denote locations west of the meridian and positive numbers denote locations east of the meridian. (The meridian passes through Greenwich, London.) The location list is terminated by a line consisting of a single "#".

Each line in the query list contains three names of locations. You can assume the first location to be Alice's home, the second location to be Bob's home and the third location to be a possible meeting point. The query list is terminated by a line consisting of a single "#".

Output Specification

For each query, output a line saying "M is x km off A/B equidistance." with M,x,A,B appropriately replaced by the location names and the calculated distance rounded to the nearest integer.

If one of the locations in the query didn't occur in the list of locations print "?" instead of the distance.

Sample Input

 

Ulm             48.700 10.500
Freiburg        47.700 9.500
Philadelphia    39.883 -75.250
SanJose         37.366 -121.933
Atlanta         33     -84
Eindhoven       52     6
Orlando         28     -82
Vancouver       49     -123
Honolulu        22     -157
NorthPole       90     0
SouthPole       -90    0
#
Ulm Freiburg Philadelphia
SanJose Atlanta Eindhoven
Orlando Vancouver Honolulu
NorthPole SouthPole NorthPole
Ulm SanDiego Orlando
NorthPole SouthPole SouthPole
Ulm Honolulu SouthPole
#

Sample Output

 

Philadelphia is 690 km off Ulm/Freiburg equidistance.
Eindhoven is 3117 km off SanJose/Atlanta equidistance.
Honolulu is 4251 km off Orlando/Vancouver equidistance.
NorthPole is 10019 km off NorthPole/SouthPole equidistance.
Orlando is ? km off Ulm/SanDiego equidistance.
SouthPole is 10019 km off NorthPole/SouthPole equidistance.
SouthPole is 1494 km off Ulm/Honolulu equidistance.



Source: University of Ulm Local Contest 2000

一道球坐标转直角坐标向量解的立体几何题。给出球上两点,则球面上有一个到两点距离相等的大圆,即大圆所在平面垂直两点连线。

求第三个点到该大圆的球面距离。

编程很容易,用map基本不会有程序上的错误。

#include <iostream>
#include <math.h>  
#include <algorithm>  
#include <stdio.h>  
#include <string>
#include <map>
using namespace std;
struct location{
    string lname;
    double x,y,z;
    friend bool operator < (location a, location b)  
    {  
        return a.lname.compare(b.lname)<0;  
    }
    friend bool operator == (location a, location b)  
    {  
        return a.lname.compare(b.lname)==0;  
    }
};
map<string,location> loc;
const double Radius = 6378.0;
const double PI = acos(-1);
double rad(double agl){
    return agl*PI/180.0;
}
int main(){
    int i,j,k;
    double lat,lng,alg,dis,vx,vy,vz;
    location p;
    string s,a,b,c;
    map<string,location>::iterator ia,ib,ic;
    loc.clear();
    while(cin>>s,s!="#"){
        cin>>lat>>lng;
        p.lname = s;
        p.x = Radius*cos(rad(lat))*cos(rad(lng));//球坐标转换
        p.y = Radius*cos(rad(lat))*sin(rad(lng));
        p.z = Radius*sin(rad(lat));
        loc[s] = p;
    }
    while(cin>>a,a!="#"){
        cin>>b>>c;
        ia = loc.find(a);    ib = loc.find(b);    ic = loc.find(c);
        if(ia==loc.end() || ib==loc.end() || ic==loc.end()){
            cout<<c<<" is ? km off "<<a<<"/"<<b<<" equidistance."<<endl;
        }
        else{
            vx = loc[a].x-loc[b].x;//AB为其两点间法平面的法向量 
            vy = loc[a].y-loc[b].y;
            vz = loc[a].z-loc[b].z;
            if(vx==0&&vy==0&&vz==0) dis = 0;
            else{
                alg = acos( (vx*loc[c].x+vy*loc[c].y+vz*loc[c].z)/sqrt(vx*vx+vy*vy+vz*vz)/sqrt(loc[c].x*loc[c].x+loc[c].y*loc[c].y+loc[c].z*loc[c].z) );
                dis = (int)(fabs(PI/2 - alg)*Radius+0.5);
            }
            cout<<c<<" is "<<dis<<" km off "<<a<<"/"<<b<<" equidistance."<<endl;
        }
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/shenchuguimo/p/6381682.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值