[JSOI2004]平衡点 / 吊打XXX
Posted szmssf
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[JSOI2004]平衡点 / 吊打XXX相关的知识,希望对你有一定的参考价值。
考虑模拟退火。
题目要我们找到一个点,使得整个系统平衡。
这个要求等价于让我们找到一个点,使得系统总能量最小。
我们退火出一个点,然后计算其能量即可。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 #include<cstdlib> 7 #include<cmath> 8 #define N 10005 9 using namespace std; 10 int read() 11 12 int x=0,f=1;char ch=getchar(); 13 while(ch<‘0‘||ch>‘9‘)if(ch==‘-‘)f=-1;ch=getchar(); 14 while(ch>=‘0‘&&ch<=‘9‘)x=(x<<3)+(x<<1)+(ch^48);ch=getchar(); 15 return x*f; 16 17 struct node 18 19 int x,y,w; 20 a[N]; 21 int n; 22 double t,ansx,ansy,sx,sy,ans=1e18; 23 const double delta=0.993; 24 double calc(double x,double y) 25 26 double res=0; 27 for(int i=1;i<=n;i++) 28 29 double dtx=x-a[i].x,dty=y-a[i].y; 30 res+=sqrt((dtx*dtx)+(dty*dty))*a[i].w; 31 32 return res; 33 34 void SA() 35 36 double x=ansx,y=ansy; 37 t=2137; 38 while(t>1e-14) 39 40 double X=x+((rand()<<1)-RAND_MAX)*t; 41 double Y=y+((rand()<<1)-RAND_MAX)*t; 42 double now=calc(X,Y); 43 double D=now-ans; 44 if(D<0) 45 46 x=X;y=Y; 47 ansx=x;ansy=y;ans=now; 48 49 else if(exp(-D/t)*RAND_MAX>rand())x=X,y=Y; 50 t*=delta; 51 52 53 void solve() 54 55 ansx=(double)sx/n;ansy=(double)sy/n; 56 SA(); 57 SA(); 58 SA(); 59 SA();SA(); 60 61 int main() 62 63 srand(44042137); 64 n=read(); 65 for(int i=1;i<=n;i++) 66 67 a[i].x=read();a[i].y=read();a[i].w=read(); 68 sx+=a[i].x;sy+=a[i].y; 69 70 solve(); 71 printf("%.3lf %.3lf\n",ansx,ansy); 72 return 0; 73
以上是关于[JSOI2004]平衡点 / 吊打XXX的主要内容,如果未能解决你的问题,请参考以下文章