TOJ-1336 Airline Hub

World Wide Flyer has landing rights at several airports throughout the world. They wish to place their central hub at the airport that minimizes the maximum direct flying distance from the hub to any other airport in the world.

Input consists of a line containing n ≤ 1000, the number of airports. n lines follow, each giving the latitude (between -90 and +90 degrees) and longitude (between -180 and +180 degrees) of an airport.

To two decimal places, give the latitude and longitude of the airport that best serves as a hub. If there are several any one will do.

Sample Input

3
3.2 -15.0
20.1 -175
-30.2 10

Output for Sample Input

3.20 -15.00



Source: Waterloo Local Contest Jan. 29, 2000

题目要求一机场坐标,该机场到其他各机场的距离的最大值是所有机场中最小的。

将所有机场构成的边按从长到短排序,从最长边开始遍历顶点,第n个顶点纪委所求点。

这是因为排在前面的边是各个顶点到其他顶点的边中距离最大的几个,当遍历到第n个顶点时,其余顶点的最长边都已遍历过,

即该点的最长边是所有顶点的最长边中最小的。

这道题按理来说应该求球面距离,但是按直线距离求也能AC(没错,飞机从地下飞)。

以下代码摘自http://blog.csdn.net/code_or_code/article/details/38877305

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
bool vis[1000];
double x[1000],y[1000];
int n;
int cnt;
struct node{
    int u,v;
    double dis;
}edge[500000];

int cmp(node a,node b)
{
    return a.dis>b.dis;
}


void cul(int u,int v)
{
    edge[cnt].u=u;
    edge[cnt].v=v;
    double l1=x[u],d1=y[u],l2=x[v],d2=y[v];
    double p = acos(-1.0);
    l1 *= p/180.0; d1 *= p/180.0;
    l2 *= p/180.0; d2 *= p/180.0;
    edge[cnt].dis=acos(cos(l1)*cos(l2)*cos(d1-d2)+sin(l1)*sin(l2));
    cnt++;
}

int main()
{
    memset(vis,true,sizeof vis);
    scanf("%d",&n);
    for(int i=0;i<n;i++)
        scanf("%lf%lf",&x[i],&y[i]);

    cnt=0;
    for(int i=0;i<n;i++)
        for(int j=i+1;j<n;j++)
        {
            cul(i,j);
        }
    sort(edge,edge+cnt,cmp);
    int num=0;
    for(int i=0;i<cnt;i++)
    {
        if(vis[edge[i].u])
        {
            num++;
            vis[edge[i].u]=false;
        }
        if(num==n-1) break;
        if(vis[edge[i].v])
        {
            num++;
            vis[edge[i].v]=false;
        }
        if(num==n-1) break;
    }
    for(int i=0;i<n;i++)
        if(vis[i]){
            printf("%.2lf %.2lf\n",x[i],y[i]);
            break;
        }

    return 0;
}

这道题的数据还有另一个问题,就是所有测试数据的答案都是到(0,0)点最近的点(这显然不对)。。。这是POJ的discuss版块中发现的,

发现者用以下代码AC了。。。

#include<stdio.h>
int main()
{
    double a,b,x,y,m=99999;
    int n;
    scanf("%d",&n);
    while(n--)
    {
        scanf("%lf%lf",&a,&b);
        if(m>a*a+b*b)
        {
            m=a*a+b*b;
            x=a;
            y=b;
        }
    }
    printf("%.2lf %.2lf\n",x,y);
    return 0;
}

我也不知道为什么会生成这样的测试数据。。。

posted @ 2017-02-04 19:22  DGSX  阅读(230)  评论(0编辑  收藏  举报