码迷,mamicode.com
首页 > Web开发 > 详细

[JSOI2004]平衡点

时间:2020-10-14 20:33:13      阅读:32      评论:0      收藏:0      [点我收藏+]

标签:print   模拟退火   double   随机   pac   lan   eal   ret   分析   

题目

请前往 [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);
} 

[JSOI2004]平衡点

标签:print   模拟退火   double   随机   pac   lan   eal   ret   分析   

原文地址:https://www.cnblogs.com/leiyuanze/p/13814108.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!