[JSOI2004]平衡点
题目
请前往 [JSOI2004]平衡点
分析
随机算法
为何不模拟退火呢?
于是(其实目前我不懂怎么判断平不平衡)
能量越小系统越平衡
\(Code\)
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const int N = 1005;
const double delta = 0.996;
int n;
struct node{int x , y , w;}p[N];
double ans_x , ans_y , ans_w;
double energy(double x , double y)
{
double res = 0;
for(register int i = 1; i <= n; i++)
{
double xx = x - p[i].x , yy = y - p[i].y;
xx = xx * xx , yy = yy * yy;
double z = sqrt(xx + yy) * p[i].w;
res += z;
}
return res;
}
void Simulate_Anneal()
{
double t = 3000;
while (t > 1e-14)
{
double xx = ans_x + (rand() * 2 - RAND_MAX) * t;
double yy = ans_y + (rand() * 2 - RAND_MAX) * t;
double ww = energy(xx , yy) , del = ww - ans_w;
if (del < 0){ans_x = xx , ans_y = yy , ans_w = ww;}
else if (exp(-del / t) * RAND_MAX > rand()) {ans_x = xx , ans_y = yy;}
t *= delta;
}
}
void solve()
{
for(register int i = 1; i <= 4; i++)
Simulate_Anneal();
}
int main()
{
scanf("%d" , &n);
double sx = 0 , sy = 0;
for(register int i = 1; i <= n; i++)
scanf("%d%d%d" , &p[i].x , &p[i].y , &p[i].w) , sx += p[i].x , sy += p[i].y;
ans_x = 1.0 * sx / n , ans_y = 1.0 * sy / n;
ans_w = energy(ans_x , ans_y);
solve();
printf("%.3lf %.3lf" , ans_x , ans_y);
}