ZOJ 2928 模拟退火 求三维费马点

来源:互联网 发布:贵州高考录取数据 编辑:程序博客网 时间:2024/05/29 14:09
#include<iostream>#include<cstring>#include<string>#include<cstdio>#include<algorithm>#include<vector>#include<map>#include<queue>#include<cmath>using namespace std;#define eps 1e-12#define N 110#define M 2001000#define ll long long#define inf 0x3f3f3f3fint n,cnt;struct P{double x,y,z;P(){}P(double _x,double _y,double _z):x(_x),y(_y),z(_z){}double len(){return sqrt(x*x+y*y+z*z);}P operator+(const P p){return P(x+p.x,y+p.y,z+p.z);}P operator-(const P p){return P(x-p.x,y-p.y,z-p.z);}P operator*(double c){return P(x*c,y*c,z*c);}}p[N],dir[30];int dblcmp(double x){return (x>eps)-(x<-eps);}void init(){for(int i=-1;i<=1;i++)for(int j=-1;j<=1;j++)for(int k=-1;k<=1;k++)dir[cnt++] = P(i,j,k);}void solve(){double step = 100;double mi = 1e10;P ans = P(0,0,0),now,nxt;for(int j=0;j<n;j++)ans = ans+p[j];ans = ans * (1.0/n);while(step>eps){nxt = ans;for(int i=0;i<cnt;i++){now = ans+dir[i]*step;double tmp = 0;for(int j=0;j<n;j++)tmp += (now-p[j]).len();if(dblcmp(tmp-mi)<0){mi = tmp;nxt = now;}}ans = nxt;step *= 0.993;}printf("%.3lf %.3lf %.3lf\n",ans.x,ans.y,ans.z);}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);solve();}return 0;}

0 0
原创粉丝点击