伪模拟退火(爬山)能过?
查看原帖
伪模拟退火(爬山)能过?
941431
Li_Feiy楼主2024/10/24 20:10

如果当前解更优,直接接受,否则不接受。如果加上 else if(exp(delta / t) * RAND_MAX > rand()) anx = nowx, any = nowy; 反而过不了。

// Problem: RUNAWAY - Run Away
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/SP34
// Memory Limit: 1 MB
// Time Limit: 13000 ms
// Date: 2024/10/24 11:10:41
// Author: Li_Feiy

#include <bits/stdc++.h>
#define arrout(a, n) rep(i, 1, n) printk(a[i])
#define arrin(a, n) rep(i, 1, n) a[i] = read()
#define rep(i, x, n) for(int i = x; i <= n; i++)
#define dep(i, x, n) for(int i = x; i >= n; i--)
#define erg(i, x) for(int i = head[x]; i; i = e[i].nex)
#define dbg(x) std::cout << #x << ":" << x << " "
#define mem(a, x) memset(a, x, sizeof a)
#define all(x) x.begin(), x.end()
#define arrall(a, n) a + 1, a + 1 + n
#define PII std::pair<int, int>
#define m_p std::make_pair
#define u_b upper_bound
#define l_b lower_bound
#define p_b push_back
#define CD const double
#define CI const int
#define int long long
#define il inline
#define ss second
#define ff first
#define itn int
int read() {
	char ch = getchar();
	int r = 0, w = 1;
	while(ch < '0' || ch > '9') w = ch == '-' ? -1 : w, ch = getchar();
	while(ch >= '0' && ch <= '9') r = (r << 3) + (r << 1) + (ch ^ 48), ch = getchar();
	return r * w;
}

void print(int x) {
	if(x < 0) putchar('-'), x = -x;
	if(x >= 10) print(x / 10);
	putchar(x % 10 + '0');
}

void printl(int x) { print(x), putchar('\n'); }
template<typename ...Args>
void printl(int t, Args... args) { printl(t), printl(args...); }

void printk(int x) { print(x), putchar(' '); }
template<typename ...Args>
void printk(int t, Args ... args) { printk(t), printk(args...); }

CI N = 2e5 + 5;
int T, m;
struct node {
	double x, y;
} a[N];
double x, y, ansx, ansy;
double calc(double x, double y) {
	double dis = std::numeric_limits<double>::max();
	rep(i, 1, m) dis = std::min(dis, sqrt((x - a[i].x) * (x - a[i].x) + (y - a[i].y) * (y - a[i].y)));
	return dis;
}
double randd(double l, double r) { return (double)rand() / RAND_MAX * (r - l) + l; }
void SA() {
	double t = 1145, tk = 1e-6, d = 0.997;
	double anx = ansx, any = ansy;
	while(t > tk) {
		double nowx = randd(std::max(anx - t, 0.0), std::min(anx + t, x * 1.0));
		double nowy = randd(std::max(any - t, 0.0), std::min(any + t, y * 1.0));
		double delta = calc(nowx, nowy) - calc(anx, any);
		if(delta > 0) ansx = anx = nowx, ansy = any = nowy;
		t *= d;
	}
}
signed main() {
	srand(108102121);
	srand(rand());
	srand(rand());
	T = read();
	while(T --) {
		x = read(), y = read(), m = read();
		rep(i, 1, m) a[i].x = read(), a[i].y = read();
		ansx = randd(0, x), ansy = randd(0, y);
		SA();
		// printf("%.3lf\n", calc(ansx, ansy));
		printf("The safest point is (%.1lf, %.1lf).\n", ansx, ansy);
	}
	return 0;
}
2024/10/24 20:10
加载中...