洛谷P1378 油滴扩展
\(\Large\textbf{Description: } \large{在一个矩形中,有\text{n}个点,n个点可以以不同的顺序进行扩散,直到碰到已经被覆盖的地方或者矩形边界停止,求剩余面积最小值。(0 \leq n \leq 6)}\\\)
\(\Large\textbf{Solution: } \large{一道搜索题。我们判断一个点是否不被覆盖比较麻烦,但是我们可以维护每个点的半径,来判断冲不冲突,算是一种普遍的思路吧。}\\\)
\(\Large\textbf{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\n", (int)(ms - ans + 0.5));
return 0;
}