题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2928
题意:给出三维空间一些点。求一个点p使得p到其他点距离之和最小。
思路:对于step,每次枚举当前答案的(x,y,z)每个加或者减step,共8种情况,计算和,更新答案。
int sgn(double x)
{
if(x>EPS) return 1;
if(x<-EPS) return -1;
return 0;
}
struct point
{
double x,y;
point(){}
point(double _x,double _y)
{
x=_x;
y=_y;
}
void get()
{
RD(x); RD(y);
}
point operator+(point a)
{
return point(x+a.x,y+a.y);
}
point operator-(point a)
{
return point(x-a.x,y-a.y);
}
double operator*(point a)
{
return x*a.y-y*a.x;
}
point operator*(double t)
{
return point(x*t,y*t);
}
double operator^(point a)
{
return x*a.x+y*a.y;
}
double len()
{
return sqrt(x*x+y*y);
}
void print()
{
printf("%.3lf %.3lf\n",x+EPS,y+EPS);
}
};
double len(point a)
{
return a.len();
}
struct point3
{
double x,y,z;
point3(){}
point3(double _x,double _y,double _z)
{
x=_x;
y=_y;
z=_z;
}
void get()
{
RD(x); RD(y); RD(z);
}
point3 operator+(point3 a)
{
return point3(x+a.x,y+a.y,z+a.z);
}
point3 operator-(point3 a)
{
return point3(x-a.x,y-a.y,z-a.z);
}
point3 operator*(point3 a)
{
return point3(y*a.z-z*a.y,z*a.x-x*a.z,x*a.y-y*a.x);
}
point3 operator*(double t)
{
return point3(x*t,y*t,z*t);
}
double operator^(point3 a)
{
return x*a.x+y*a.y+z*a.z;
}
point3 operator/(double t)
{
return point3(x/t,y/t,z/t);
}
double len()
{
return sqrt(x*x+y*y+z*z);
}
void print()
{
printf("%.3lf %.3lf %.3lf\n",x+EPS,y+EPS,z+EPS);
}
};
double len(point3 a)
{
return a.len();
}
int n;
point3 p[N],d[N];
int main()
{
Rush(n)
{
int i,j,k;
FOR1(i,n) p[i].get();
point3 ans=point3(0,0,0),cur;
double step=2000,Min=dinf,temp;
int x=0;
FOR(i,-1,1) FOR(j,-1,1) FOR(k,-1,1)
{
d[x++]=point3(i,j,k);
}
while(step>EPS)
{
FOR0(i,x)
{
temp=0; cur=ans+d[i]*step;
FOR1(j,n) temp+=(p[j]-cur).len();
if(sgn(temp-Min)==-1) ans=cur,Min=temp;
}
step*=0.99;
}
ans.print();
}
}