您的位置:首页 > 其它

POJ 1379 模拟退火的起点选择

2015-08-24 21:55 411 查看
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <iomanip>
using namespace std;
const int maxn = 1010;
int T, n, X, Y;
struct Point
{
	double x, y, r;
	Point() {}
	Point(double xx, double yy): x(xx), y(yy) {}
};
Point p[maxn], m[maxn], t, ans;
double dis(Point a, Point b)
{
	return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
double judge(Point &t)
{
	double val = dis(t, p[0]);
	for (int i = 1; i < n; i++)
		val = min(val, dis(t, p[i]));
	return val;
}
Point RandPoint(Point a, Point b)
{
	Point tmp(a.x +  (b.x - a.x) * (rand() % 1001 / 1000.0), a.y + (b.y - a.y) * (rand() % 1001 / 1000.0));
	tmp.r = judge(tmp);
	return tmp;
}
void solve()
{
	m[0] = Point(0, 0); m[1] = Point(X, Y); m[2] = Point(0, Y); m[3] = Point(X, 0);
	for (int i = 4; i < 20; i++)
		m[i] = RandPoint(m[0], m[1]);
	for (double step = max(X, Y), rate = 0.9; step > 0.01; step *= rate)
		for (int i = 0; i < 20; i++)
			for (int j = 0; j < 20; j++)
			{
				t = RandPoint(Point(max(0.0, m[i].x - step), max(0.0, m[i].y - step)), Point(min((double)X, m[i].x + step), min((double)Y, m[i].y + step)));
				if (t.r > m[i].r) m[i] = t;
			}
	ans = m[0];
	for (int i = 1; i < 20; i++)
		if (ans.r < m[i].r)
			ans = m[i];
	cout << setprecision(1) << fixed << "The safest point is (" << ans.x << ", " << ans.y << ")." << endl;
}
int main(int argc, char const *argv[])
{
	cin >> T;
	while (T--)
	{
		cin >> X >> Y >> n;
		for (int i = 0; i < n; i++)
			cin >> p[i].x >> p[i].y;
		solve();
	}
	return 0;
}


自己写了一个模拟退火,rate需要定为0.99才能够出正确结果,然而tle;

网上膜拜了神牛的代码,把起点定为多个,四个甚至更多,这样走的步数少得多,rate 0.7都能出结果;

学习了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: