Uva 11168 Airport(凸包)

62 篇文章 0 订阅
7 篇文章 0 订阅

题目地址:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2109

思路:

1.所找直线一定为凸包上的边,故可枚举凸包上的边,求最短距离和。

2.由于所有点在直线同侧所以所有abs(A*x+B*y+C)/sqrt(A*A+B*B)等于(A*x+B*y+C)/sqrt(A*A+B*B)或-(A*x+B*y+C)/sqrt(A*A+B*B)。则点到直线的距离和可以O(1)时间内获得:fabs(A*sum(x[i])+B*sum(y[i])+C*(n-2)) (i=1---n且i不在所枚举的直线上)

3.两点式转化为一般式:










4.若只有一个点,结果为0.


#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define debug
using namespace std;
const double eps=1e-6;
struct Point
{
    double x,y;
    Point(double x=0.0,double y=0.0):x(x),y(y) {}
    void read()
    {
        scanf("%lf%lf",&x,&y);
    }
};
typedef Point Vector;

int dcmp(double x)
{
  if(fabs(x)<eps) return 0;
  else return x<0?-1:1;
}

bool operator < (const Point &a,const Point &b)
{
  return a.x<b.x||(a.x==b.x&&a.y<b.y);
}

Vector operator - (Vector A,Vector B){return Vector(A.x-B.x,A.y-B.y);}

double Cross(Vector A,Vector B){return A.x*B.y-A.y*B.x;}

int ConvexHull(Point* p,int n,Point* ch)
{
  sort(p,p+n);
  int m=0;
  for(int i=0;i<n;i++)
  {
    while(m>1&&Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) m--;
    ch[m++]=p[i];
  }
  int k=m;
  for(int i=n-2;i>=0;i--)
  {
    while(m>k&&Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) m--;
    ch[m++]=p[i];
  }
  if(n>1) m--;
  return m;
}

const int maxn=10000+50;
const double INF=1e20;

int n;
Point p[maxn],convex[maxn];

int main()
{
#ifdef debu
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
#endif // debug
    int t,cas=0;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        double ans=INF;
        double totx=0,toty=0;
        for(int i=0; i<n; i++)
        {
            p[i].read();
            totx+=p[i].x;
            toty+=p[i].y;
        }
        if(n==1)
        {
           printf("Case #%d: %.3f\n",++cas,0.0);
           continue;
        }
        int num=ConvexHull(p,n,convex);
        for(int i=0; i<num; i++)
        {
            double A,B,C,tot=0;
            Point p1=convex[i],p2=convex[(i+1)%num];
            A=p2.y-p1.y,B=p1.x-p2.x,C=p2.x*p1.y-p1.x*p2.y;
            tot+=(totx-p1.x-p2.x)*A+(toty-p1.y-p2.y)*B+C*(n-2);
            tot/=sqrt(A*A+B*B);
            ans=min(ans,fabs(tot));
        }
        printf("Case #%d: %.3f\n",++cas,ans/n);
    }
    return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值