又一个被模拟退火带入歧途的
  • 板块学术版
  • 楼主封禁用户
  • 当前回复7
  • 已保存回复7
  • 发布时间2024/10/7 18:49
  • 上次更新2024/10/7 21:02:12
查看原帖
又一个被模拟退火带入歧途的
608410
封禁用户楼主2024/10/7 18:49

RT,孩子要疯了。P1378样例不过求条

#include<bits/stdc++.h>
using namespace std;
const int Tmax = 1145141919;
const double Tmin = 0.0000000001;
const int delta = 0.9999;
const int maxn = 6 + 5;
const int pi = acos(-1);
const int RANDMAX = (unsigned)-1;
const int MAX_TIME = 0.9;
mt19937 ran(time(0));
int n, sx, sy, ex, ey;
double ans = INT_MAX;
int a[maxn][2];
double r[maxn];
inline int read() {
	int ret = 0, f = 1;char ch = getchar();
	while (ch < '0' || ch > '9') {
		if (ch == '-') f = -f;
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9') {
		ret = (ret << 1) + (ret << 3) + (ch ^ 48);
		ch = getchar();
	}
	return ret * f;
}

double dis(double xa, double ya, double xb, double yb) {
	return sqrt((xa - xb) * (xa - xb) + (ya - yb) * (ya - yb));
}

double calc() {
	double sum = 0;
	for(int i = 1; i <= n; i++) {
		r[i] = min({abs(sx - a[i][0]), abs(ex - a[i][0]), abs(sy - a[i][1]), abs(ey - a[i][1])});
		for(int j = 1; j < i; j++) {
			if(dis(a[i][0], a[i][1], a[j][0], a[j][1]) > r[j]) r[i] = min(r[i], dis(a[i][0], a[i][1], a[j][0], a[j][1]) - r[j]);
			else r[i] = 0;
		}
		sum += r[i] * r[i] * pi;
	}
	return (double)abs(ex - sx) * abs(ey - sy) - sum;
}

void sa() {
	double t = Tmax;//初始温度
	while (t >= Tmin) {//一直降温直到温度极小 
		int x = ran() % n + 1, y = ran() % n + 1;//随机交换x与y的位置
		swap(a[x][1], a[y][1]), swap(a[x][0], a[y][0]);
		double cnt = calc(); 
		if (cnt < ans) ans = cnt;	//比当前答案更优
		else if (exp((double)(ans - cnt) / t) * RANDMAX < (double)ran()) {	//不比当前优,以一定概率转移
			swap(a[x][1], a[y][1]), swap(a[x][0], a[y][0]);
		}
		t *= delta;
	}
}

int main() {
	srand(time(0)); 
	n = read();sx = read(), sy = read(), ex = read(), ey = read();
	for (int i = 1;i <= n;i++) a[i][0] = read(), a[i][1] = read();
	
	ans = calc();
	while ((double)clock() / CLOCKS_PER_SEC <= MAX_TIME) sa();
	printf("%d", (int)ans);
	return 0;
} 
2024/10/7 18:49
加载中...