bzoj3680 -- 模拟退火
模拟退火裸题(输出"nan nan"可以AC)
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<cstdlib> 6 using namespace std; 7 #define N 10010 8 struct Node{ 9 double x,y,z; 10 }a[N]; 11 double x,y,T=100000,Now,Ax,Ay,X,Y,N2,Min=1e17; 12 int i,j,k,n,m; 13 inline double Dist(double x,double y,Node a){ 14 return sqrt((x-a.x)*(x-a.x)+(y-a.y)*(y-a.y)); 15 } 16 inline double Calc(double X,double Y){ 17 double Ans=0; 18 for(int i=1;i<=n;i++)Ans+=Dist(X,Y,a[i])*a[i].z; 19 if(Ans<Min)Ax=X,Ay=Y,Min=Ans; 20 return Ans; 21 } 22 inline double Getrand(){ 23 return rand()%1000/1000.0; 24 } 25 inline void SA(){ 26 while(T>0.001){ 27 X=x+T*(Getrand()*2-1);Y=y+T*(Getrand()*2-1); 28 N2=Calc(x,y)-Calc(X,Y); 29 if(N2>0||exp(N2/T)>Getrand())x=X,y=Y; 30 T*=0.993; 31 } 32 for(int i=1;i<=1000;i++){ 33 X=Ax+T*(Getrand()*2-1);Y=Ay+T*(Getrand()*2-1);Calc(X,Y); 34 } 35 } 36 int main(){ 37 srand(10086); 38 scanf("%d",&n); 39 for(i=1;i<=n;i++)scanf("%lf%lf%lf",&a[i].x,&a[i].y,&a[i].z),x+=a[i].x,y+=a[i].y; 40 x/=n;y/=n; 41 SA(); 42 printf("%.3lf %.3lf\n",Ax,Ay); 43 return 0; 44 }