题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2928
参考学习的yamiedie_的博文:http://blog.youkuaiyun.com/u013654696/article/details/22336419
关于爬山算法和模拟退火的简介:http://www.cnblogs.com/heaad/archive/2010/12/20/1911614.html
This year's mathematical contest in modeling in ZJU will come soon. The students loving the contest have already made their teams. We consider a simple model: A team contains three students, one of them is good at maths, the second of them is good at computer, and the third one is good at writing. Now they want to estimate their team's relative power level in all participant teams. They use their grades in school instead of their real modeling abilities now because before the contest no other criterions more properly can be used. The grade of a student is a nonnegative real number no more than 1000. A team's modeling ability can be represented by three real numbers a, b, and c. a is the grade of the student which is good at maths, b is the grade of the one which is good at computer, and c is the grade of the one which is good at writing. If they know the average modeling ability of all teams, each team can compare their own team's modeling ability with the average modeling ability and then estimates their relative modeling power level in all teams.
Assume two teams' modeling abilities are a1, b1, c1 and a2, b2, c2 respectively, then the difference between their modeling abilities is defined as sqrt((a1-a2)^2+(b1-b2)^2+(c1-c2)^2). The average modeling ability of all teams is three real numbers which can be considered as a team's modeling ability, and the sum of the differences between this modeling ability and all teams' modeling abilities is minimum.
Your task is to calculate the average modeling ability of all teams.
Input
There are multiple test cases. Each teat case begins with a line containing a integer n, 3 <= n <= 100, which is the number of all teams. Then n lines follow, each line contains three real numbers ai, bi and ci, 0.00 <= ai, bi, ci <= 1000.00, which is a team's modeling ability.
Output
For each test case, print the average modeling ability of all teams in a line rounded to three decimal places after the decimal point. It is guaranteed that the answer is unique.
Sample Input
4
100.00 100.00 100.00
1000.00 100.00 100.00
100.00 1000.00 100.00
100.00 100.00 1000.00
Sample Output
250.000 250.000 250.000
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
using namespace std;
#define eps 1e-8
struct point
{
double x,y,z;
point(){}
point(double _x,double _y,double _z)
{
x=_x;y=_y;z=_z;
}
point operator - (const point &b) const
{
return point(x-b.x,y-b.y,z-b.z);
}
double len()
{
return sqrt(x*x+y*y+z*z);
}
}p[105],now;
int dir[30][3];
int n;
double dis(point a,point b)
{
return (a-b).len();
}
void init() //生成三维的方向数组
{
int x=0;
for (int i=-1;i<=1;i++)
{
for (int j=-1;j<=1;j++)
{
for (int k=-1;k<=1;k++)
{
dir[x][0]=i;dir[x][1]=j;dir[x][2]=k;++x;
}
}
}
return;
}
double zh(point now)//求出距离之和
{
double ans=0;
for (int i=0;i<n;i++)
{
ans+=dis(now,p[i]);
}
return ans;
}
int main()
{
init();//生成三维方向数组
while (scanf("%d",&n)!=EOF)
{
for (int i=0;i<n;i++)
{
scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].z);
}
now=point(0.0,0.0,0.0);
double stp=-1,ans=zh(now);
for (int i=0;i<n;i++)//找到初始步长,由于答案不可能在多面体外部,所以初始步长可以设为到点的距离最大值
{
double x=dis(now,p[i]);
if (x>stp) stp=x;
}
while (stp>eps)//步长为0时停止循环,此时已经趋于稳定
{
point pre=now;
double ans=zh(now);
for (int i=0;i<27;i++)
{
point unow=point(pre.x+dir[i][0]*stp,pre.y+dir[i][1]*stp,pre.z+dir[i][2]*stp);//向i方向前进一个步长
double tmp=zh(unow);
if (tmp<ans) {ans=tmp;now=unow;}//若当前点优于现在的最优解,则更新最优解(注意作为爬山起点的pre点暂时没有改变)
}
stp=stp*0.992;//减少步长,使步长趋于稳定(选取的数字要在不超时的可能下尽量大一点)
}
printf("%.3lf %.3lf %.3lf\n",now.x,now.y,now.z);
}
return 0;
}