AirPort,Uva 11168
题意:
给出n个点,找一条直线,使得所有的点在直线的一侧(或者在直线上),并且所有的点到直线距离的平均最小。
解题:
对于所有的点我们先建立凸包,直觉可以发现直线在凸包上回会比和凸包相离要合适。所以依次枚举出所有的凸包边。事先计算出全部的点的坐标和,可以在更短的时间内求得全部点到直线的距离,因为所有的点在直线同一侧,所以 Ax0+By0+C A x 0 + B y 0 + C 具有相同的正负性。通过点到直线的距离公式就可以计算出来。
|Axsum+Bysum+nC|A2+B2√ | A x s u m + B y s u m + n C | A 2 + B 2 。
#include <bits/stdc++.h>
using namespace std;
struct Point{
double x,y;
Point(double x,double y):x(x),y(y){}
Point(){}
};
typedef Point Vector;
Point operator+(Point a,Point b){return Point(a.x+b.x,a.y+b.y);}
Point operator-(Point a,Point b){return Point(a.x-b.x,a.y-b.y);}
Point operator*(Point a,double D){return Point(a.x*D,a.y*D);}
Point operator/(Point a,double D){return Point(a.x/D,a.y/D);}
bool operator < (const Point &a, const Point & b){return a.x < b.x || (a.x == b.x && a.y < b.y);}
const double eps=1e-10;
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 dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;}
double dot(Vector a,Vector b){return a.x*b.x+a.y*b.y;}
double length(Vector a){return sqrt(dot(a,a));}
double angle(Vector a,Vector b){return acos( dot(a,b)/length(a)/length(b) );}
double angle(Vector a){return atan2(a.y,a.x);}
double cross(Vector a,Vector b){return a.x*b.y-a.y*b.x;}
double area2(Point A,Point B,Point C){return cross(B-A,C-A);}
Vector rotate(Vector a,double rad){
return Vector(a.x*cos(rad)-a.y*sin(rad),a.x*sin(rad)+a.y*cos(rad));
}
Vector normal(Vector a){double l=length(a);return Vector(-a.y/l,a.x/l);}
double torad(double deg){return deg/180 * M_PI;}
double distanceToLine(Point P,Point A,Point B)
{
Vector v1=B-A,v2=P-A;
return fabs(cross(v1,v2))/length(v1);
}
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&&dcmp(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&&dcmp(cross(ch[m-1]-ch[m-2],p[i]-ch[m-2]))<=0)m--;
ch[m++]=p[i];
}
if(n>1)m--;
return m;
}
double sumx,sumy;
double calDistanceSum(int n,Point p1,Point p2){
double x1,y1,x2,y2;
x1=p1.x;y1=p1.y;
x2=p2.x;y2=p2.y;
double A=y2-y1,B=x1-x2,C=x2*y1-x1*y2;
double sum = fabs(A*sumx+B*sumy+n*C)/sqrt(A*A+B*B);
return sum;
}
const int maxn = 1e4+10;
Point P[maxn],ch[maxn];
int main()
{
int T,cas=1;
scanf("%d",&T);
while(T--) {
int n;
scanf("%d",&n);
sumx=0,sumy=0;
for(int i=0;i<n;i++) {
scanf("%lf%lf",&P[i].x,&P[i].y);
sumx+=P[i].x;sumy+=P[i].y;
}
if(n<=2){printf("Case #%d: 0.000\n",cas++);continue;}
int m=convexHull(P,n,ch);
double mindis=0x3f3f3f3f,dis;
for(int i=0;i<m;i++) {
dis=calDistanceSum(n,ch[i],ch[(i+1)%m]);
mindis=dis<mindis?dis:mindis;
}
printf("Case #%d: %.3lf\n",cas++,mindis/n);
}
return 0;
}