题目链接:https://www.luogu.org/problem/P1337
以x为原点,将力分解成横纵方向的力,每次退火时单独对答案的横纵坐标进行判断是否更新答案
#include<iostream> #include<stdio.h> #include<algorithm> #include<cmath> using namespace std; #define eps 1e-6 #define maxn 1005 int n; double T,dx,X,Y,x,y; struct node{ double x,y,w; }p[maxn],a,ans; void SA() { T=20000;dx=0.98; X=0;Y=0; while(T>eps) { double c; X=Y=0; for(int i=1;i<=n;i++) { if(a.x==p[i].x) { if(a.y<p[i].y)Y+=p[i].w; else if(a.y>p[i].y)Y-=p[i].w; } else if(a.y==p[i].y) { if(a.x<p[i].x)X+=p[i].w; else if(a.x>p[i].x)X-=p[i].w; } else { c=sqrt((a.x-p[i].x)*(a.x-p[i].x)+(a.y-p[i].y)*(a.y-p[i].y)); X+=p[i].w*(p[i].x-a.x)/c;Y+=p[i].w*(p[i].y-a.y)/c; } } c=sqrt(X*X+Y*Y); if(x>abs(X))ans.x=a.x,x=abs(X); if(y>abs(Y))ans.y=a.y,y=abs(Y); a.x+=T*X/20000; a.y+=T*Y/20000; T*=dx; } } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].w); ans.x=ans.y=0;a.x=a.y=0; x=y=9999999; SA(); printf("%.3lf %.3lf ",ans.x,ans.y); return 0; }