uva11168 Airport

It is no coincidence that in no known language does the phrase ‘As
pretty as an Airport’ appear. Douglas Adams There is a small town with
n houses. The town needs an airport. An airport is basically a very
long, very straight road. Think of it as an in nite line. We need to
build the airport such that the average distance from each house to
the airport is as small as possible. However, no one wants to walk
across the runway, so all of the houses must be on the same side of
the airport. (Some houses may be a distance of zero away from the
runway, but that’s ok; we’ll give them some free ear plugs.) Where
should we build the airport, and what will be the average distance?
Input The rst line of input gives the number of cases, N ( 65). N
test cases follow. Each one is a line containing n (0 < n 10000),
followed by n lines giving the xy
-coordinates of the houses. All coordinates are integers with absolute value of at most 80,000. Output For each test case, output one line
containing ` Case # x : ’ followed by the average distance from the
airport to the houses, with 3 digits after the decimal point. No
answer will be within 10

显然选择的直线一定在凸包上。
但是如果对于凸包上的每条边暴力求距离是O(n2)的。
可以把直线写成一般式Ax+By+C=0,因为所有点都在直线的同一侧,距离之和可以写成

|Ani=1xi+Bni=1yi+Cn|A2+B2

预先求出横纵坐标之和就可以做到O(n),加上排序O(nlogn)
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const double eps=1e-8,oo=1e15;
double cmp(double x)
{
    if (x>eps) return 1;
    if (fabs(x)<eps) return 0;
    return -1;
}
struct vector
{
    double x,y;
    void rd()
    {
        scanf("%lf%lf",&x,&y);
    }
    bool operator < (const vector &v) const
    {
        return cmp(x-v.x)==-1||(cmp(x-v.x)==0&&cmp(y-v.y)==-1);
    }
    bool operator == (const vector &v) const
    {
        return cmp(x-v.x)==0&&cmp(y-v.y)==0;
    }
    vector operator + (const vector &v) const
    {
        return (vector){x+v.x,y+v.y};
    }
    vector operator - (const vector &v) const
    {
        return (vector){x-v.x,y-v.y};
    }
    vector operator * (const double &k) const
    {
        return (vector){x*k,y*k};
    }
    vector operator / (const double &k) const
    {
        return (vector){x/k,y/k};
    }
}a[10010],f[10010];
typedef vector point;
double dot(vector v,vector u)
{
    return v.x*u.x+v.y*u.y;
}
double cross(vector v,vector u)
{
    return v.x*u.y-v.y*u.x;
}
void line(point p1,point p2,double &A,double &B,double &C)
{
    A=p2.y-p1.y;
    B=p1.x-p2.x;
    C=p2.x*p1.y-p1.x*p2.y;
}
double solve()
{
    int m,n,mm,nn;
    double sx=0,sy=0,ans=oo,A,B,C;
    scanf("%d",&n);
    nn=n;
    for (int i=1;i<=n;i++) a[i].rd(),sx+=a[i].x,sy+=a[i].y;
    sort(a+1,a+n+1);
    n=unique(a+1,a+n+1)-a-1;
    if (n==1) return 0;
    m=0;
    for (int i=1;i<=n;i++)
    {
        while (m>1&&cmp(cross(f[m]-f[m-1],a[i]-f[m-1]))==-1) m--;
        f[++m]=a[i];
    }
    mm=m;
    for (int i=n-1;i;i--)
    {
        while (m>mm&&cmp(cross(f[m]-f[m-1],a[i]-f[m-1]))==-1) m--;
        f[++m]=a[i];
    }
    for (int i=1;i<=m-1;i++)
    {
        line(f[i],f[i+1],A,B,C);
        ans=min(ans,fabs(A*sx+B*sy+nn*C)/sqrt(A*A+B*B));
    }
    return ans/nn;
}
int main()
{
    int T,K;
    scanf("%d",&T);
    for (int K=1;K<=T;K++)
        printf("Case #%d: %.3f\n",K,solve());
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值