正题
题目链接:https://www.luogu.com.cn/problem/P1337
题目大意
nnn个点有重量wiw_iwi,求重心。
解题思路
模拟退火随机找一个重心然后不断接近即可。
codecodecode
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
using namespace std;
const int N=1100;
const double Delit=0.993;
int n;double x[N],y[N],v[N],ansx,ansy,ans;
double calc(double nx,double ny){double ans=0;for(int i=1;i<=n;i++){double zx=x[i]-nx,zy=y[i]-ny;ans+=sqrt(zx*zx+zy*zy)*v[i];}return ans;
}
void S_A(){double x=ansx,y=ansy;double t=2000;while(t>1e-14){double nx=x+((rand()<<1)-RAND_MAX)*t;double ny=y+((rand()<<1)-RAND_MAX)*t;double now=calc(nx,ny),k=now-ans; double now=calc(nx,ny),k=now-ans;printf("%d %lf %lf %lf\n",rand(),nx,ny,now);break;if(k<0){ans=now;x=nx;y=ny;ansx=nx;ansy=ny;}else if(exp(-k/t)*RAND_MAX>rand())x=nx,y=ny;t=t*Delit;}return;
}
void Solve(){ansx/=n;ansy/=n;ans=calc(ansx,ansy);S_A();S_A();S_A();return;
}
int main()
{srand(19260817);scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%lf%lf%lf",&x[i],&y[i],&v[i]);ansx+=x[i];ansy+=y[i];}Solve();printf("%.3lf %.3lf",ansx,ansy);
}