题意:给你n个点,求一个点到这些点的距离和最小,输出距离。
题解:模拟退火,温度是步长,向四个方向移动。贪心的选择最佳的方向走。
AC代码:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<math.h>
#define INF 1000000000
#define T 100 //初始温度
#define delta 0.98//温度下降速度
#define eps 1e-8 //终止温度
double Random()//随机接受
{
double x=rand()*1.0/RAND_MAX;
return x;
}
struct point
{
double x,y;
point(){}
point(double x,double y)
{
this->x=x;
this->y=y;
}
}a[105];
int n;
int dir[4][2]={
{1,0},
{-1,0},
{0,1},
{0,-1}
};
double dist(point a,point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double Search()
{
point start=a[0];//种子点逐渐接近局部最优
double t=T;
double ans=INF;
while(t>eps)
{
for(int i=0;i<4;i++)
{
point p=point(start.x+dir[i][0]*t,start.y+dir[i][1]*t);//这里为什么要*t呢
double now=0; //因为我们模拟向这个方向走t的距离,
for(int i=0;i<n;i++) //然后根据模拟退火最后移动距离接近0的时候就是答案
now+=dist(a[i],p);
double dE=ans-now;
if(dE>0)start=p,ans=now;
}
t*=delta;
}
return ans;
}
int main()
{
srand(time(0));
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%lf%lf",&a[i].x,&a[i].y);
printf("%.f\n",Search());
}