模拟退火 11 pts 求助!

P1337 [JSOI2004] 平衡点 / 吊打XXX

@[LHTCFLS](/user/436107) 这样写。 说下错误: - 直接 `rand() / RAND_MAX` 不会是浮点数,会变成 $0$。这是主要问题。 - 卡时。 - 微调一下参数,要不然卡时卡不满。 不知道是怎么回事,我交了 3 发只过了 2 发,应该是退火内部哪里写错了。 ```cpp #include<bits/stdc++.h> using namespace std; #define int long long #define inf 0x3f #define inf_db 127 #define ls id << 1 #define rs id << 1 | 1 #define re register #define endl '\n' typedef pair <int,int> pii; const int MAXN = 1e3 + 10; int n,x[MAXN],y[MAXN],w[MAXN]; double ansx,ansy,dis; double calc(double nx,double ny) { double res = 0; for(int i = 1;i <= n;++i) { double dx = x[i] - nx,dy = y[i] - ny; res += sqrt(dx * dx + dy * dy) * w[i]; } if(res < dis) dis = res,ansx = nx,ansy = ny; return res; } void SimulateAnneal() { double t = 3000; double nowx = ansx,nowy = ansy; while(t > 1e-15) { double nxtx = nowx + t * (rand() * 2 - RAND_MAX); double nxty = nowy + t * (rand() * 2 - RAND_MAX); double delta = calc(nxtx,nxty) - calc(nowx, nowy); if(delta < 0 || exp(-delta / t) * RAND_MAX > rand()) nowx = nxtx,nowy = nxty; t *= 0.99522; } } signed main() { srand(time(0)); cin >> n; for(int i = 1;i <= n;i++) { cin >> x[i] >> y[i] >> w[i]; ansx += x[i],ansy += y[i]; } ansx /= n,ansy /= n,dis = calc(ansx,ansy); while ((double)clock() / CLOCKS_PER_SEC < 0.97) SimulateAnneal(); printf("%.3lf %.3lf",ansx,ansy); return 0; } ```
by FastFourierTransform @ 2023-10-15 17:46:46


@[FastFourierTransform](/user/806728) 谢谢!
by Creeper_l @ 2023-10-15 18:51:35


|