[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 
View Code

 

以上是关于[JSOI2004]平衡点 / 吊打XXX的主要内容,如果未能解决你的问题,请参考以下文章

P1337 [JSOI2004]平衡点 / 吊打XXX

P1337 [JSOI2004]平衡点 / 吊打XXX

P1337 [JSOI2004]平衡点 / 吊打XXX

P1337 [JSOI2004]平衡点 / 吊打XXX

[BZOJ3680][JSOI2004]平衡点 / 吊打XXX

[luogu1337][bzoj3680][JSOI2004]平衡点 / 吊打XXX