洛谷P1378 油滴扩展

(Large extbf{Description: } large{在一个矩形中,有 ext{n}个点,n个点可以以不同的顺序进行扩散,直到碰到已经被覆盖的地方或者矩形边界停止,求剩余面积最小值。(0 leq n leq 6)}\)

(Large extbf{Solution: } large{一道搜索题。我们判断一个点是否不被覆盖比较麻烦,但是我们可以维护每个点的半径,来判断冲不冲突,算是一种普遍的思路吧。}\)

(Large extbf{Code: })

#include <cmath>
#include <cstdio>
#include <algorithm>
#define LL long long
#define gc() getchar()
#define rep(i, a, b) for(int i = (a); i <= (b); ++i)
using namespace std;
const int N = 10;
const double pi = 3.1415926535;
int n, vis[N];
double X1, X2, Y1, Y2, ms, ans, r[N], x[N], y[N];

inline double fabs(double a) { return a < 0 ? -a : a; }

inline double min(double a, double b) { return a > b ? b : a; }

inline double max(double a, double b) { return a > b ? a : b; }

inline double count(int cur) {
	double R;
	R = min(min(fabs(x[cur] - X1), fabs(X2 - x[cur])), min(fabs(y[cur] - Y1), fabs(Y2 - y[cur])));
	rep(i, 1, n) {
		if (i == cur || !vis[i]) continue;
		double dis = sqrt((x[i] - x[cur]) * (x[i] - x[cur]) + (y[i] - y[cur]) * (y[i] - y[cur]));
		R = min(R, max(0.0, dis - r[i]));
	}
	return R;
}

inline void dfs(int num, double sum) {
	if (num == n + 1) { ans = max(ans, sum); return; }
	rep(i, 1, n) {
	        if (!vis[i]) {
			vis[i] = 1;
			r[i] = count(i);
			dfs(num + 1, sum + pi * r[i] * r[i]);
			vis[i] = 0;
		}
	}
}

int main() {
	scanf("%d%lf%lf%lf%lf", &n, &X1, &Y1, &X2, &Y2);
	rep(i, 1, n) scanf("%lf%lf", &x[i], &y[i]);
	ms = fabs(X1 - X2) * fabs(Y1 - Y2);
	dfs(1, 0);
	printf("%d
", (int)(ms - ans + 0.5));
	return 0;
} 
原文地址:https://www.cnblogs.com/Miraclys/p/12421313.html