这个题目算是一个模拟退火的板子题
物重一定,绳子越短,重物越低,势能越小,势能又与物重成正比
使得$sum_{i=1}^nd[i]*w[i]$也就是总的重力势能最小,可以使得系统平衡
交了两面半。。。我怕是非洲大酋长
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <cmath> #include<ctime> using namespace std; #define il inline #define re register #define ll long long #define gc getchar() inline int read() { re int x(0),f(1);re char c(gc); while(c>'9'||c<'0')f=c=='-'?-1:1,c=gc; while(c>='0'&&c<='9')x=x*10+c-48,c=gc; return f*x; } const int N=10100; const double D=0.98,eps=1e-15; double n; double x[N],y[N],w[N]; il double f(double p,double q) { double d=0; for(int i=1;i<=n;++i) d+=w[i]*sqrt((p-x[i])*(p-x[i])+(q-y[i])*(q-y[i])); return d; } double dx,dy,T,nx,ny,ns,ax,ay,as,ds; il void sa() { for(int i=1;i<=n;++i) dx+=x[i],dy+=y[i]; dx/=n,dy/=n,ds=f(dx,dy); T=101000; while(T>eps) { nx=dx+((rand()*2)-RAND_MAX)*T; ny=dy+((rand()*2)-RAND_MAX)*T; ns=f(nx,ny); if(ns<ds) dx=nx,dy=ny,ds=ns; else if(rand()<exp((ds-ns)/T)*RAND_MAX) dx=nx,dy=ny,ds=ns; T*=D; if(ds<as) as=ds,ax=dx,ay=dy; } } int main() { srand(time(0)); n=read(); for(int i=1;i<=n;++i) scanf("%lf%lf%lf",x+i,y+i,w+i); ax=x[1],ay=y[1];as=f(x[1],y[1]); sa(),sa(),sa(),sa(); printf("%.3lf %.3lf",ax,ay); return 0; }