社区讨论
神奇模拟淬火
P1337[JSOI2004] 平衡点 / 吊打XXX参与者 4已保存回复 3
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 3 条
- 当前快照
- 1 份
- 快照标识符
- @mi1a37zo
- 此快照首次捕获于
- 2025/11/16 13:31 3 个月前
- 此快照最后确认于
- 2025/11/17 09:10 3 个月前
https://www.luogu.com.cn/discuss/1198672
这个帖子的奆佬提出了模拟淬火,于是我动手实现了一下,发现正确率还是可以的。
但是理论上来说,刚开始时搜的比较密集,而后期就不密集了,应该难以得到正确答案,但是我的代码却能够得到69~100分的成绩
code:
CPP#include<bits/stdc++.h>
using namespace std;
int n;
int x[1009];
int y[1009];
int w[1009];
double ansx, ansy, answ;
double engery(double _x, double _y) {
double r = 0, dx, dy;
for(int i = 1; i <= n; i++) {
dx = _x - x[i];
dy = _y - y[i];
r += sqrt(dx * dx + dy * dy) * w[i];
}
return r;
}
void sa() {
double t = 1e-15;
while(t <= 3000) {
double ex = ansx + (rand() * 2.0 - RAND_MAX)*t;
double ey = ansy + (rand() * 2.0 - RAND_MAX)*t;
double ew = engery(ex, ey);
double de = ew - answ;
if(de < 0) {
ansx = ex;
ansy = ey;
answ = ew;
}else if(exp(-de/t) * RAND_MAX > rand()) {
ansx = ex;
ansy = ey;
}
t*=1.003;
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
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;
answ = engery(ansx, ansy);
while((double)clock()/CLOCKS_PER_SEC<0.95)sa();
printf("%.3lf %.3lf",ansx,ansy);
return 0;
}
回复
共 3 条回复,欢迎继续交流。
正在加载回复...