题目描述
给定n个点,求关于这个n个点的广义费马点。
题目梗概
必须折服于先人的智慧。
初值随便给个位置,每次随机一个角度走温度的距离。
概率函数为 eΔ/T 。
过了之后感觉非常神奇。
#include<cstdio>
#include<cmath>
#include<cstdlib>
using namespace std;
const int maxn=105;
const double coe=0.99,eps=0.01,PI=acos(-1);
struct jz{
double x,y;
jz(){}
jz(double a,double b):x(a),y(b){}
}a[maxn],now(0,0);
int n;
double sqr(double x){return x*x;}
double dis(jz x,jz y){return sqrt(sqr(x.x-y.x)+sqr(x.y-y.y));}
double work(jz x){
double num=0;
for (int i=1;i<=n;i++) num+=dis(x,a[i]);
return num;
}
bool check(double x,double tem){
if (x<=0) return 1;
return rand()<=exp(-x/tem)*RAND_MAX;
}
int main(){
srand(4378443);
freopen("exam.in","r",stdin);
freopen("exam.out","w",stdout);
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%lf%lf",&a[i].x,&a[i].y);
for (double tem=100000;tem>eps;tem*=coe)
for (int i=1;i<=100;i++){
double jd=PI*2*rand()/RAND_MAX;
jz xx(now.x+cos(jd)*tem,now.y+sin(jd)*tem);
if (check(work(xx)-work(now),tem)) now=xx;
}
printf("%.0lf\n",work(now));
return 0;
}