有 \(n\) 个打乱的点的 \(x,\ y\) 轴坐标,现在告诉你这 \(2\times n\) 个值,问最小的矩形面积能覆盖住n个点且矩形长和宽分别与 \(x,\ y\) 轴平行。
\(n\leq10^5,\ 1\leq x,\ y\leq10^9\)
贪心
先将 \(a_i\) 升序排序,方便接下来的操作
设将这 \(2\times n\) 个值分配为 \((x_i,\ y_i)\)
则 \(ans=\min\{\max\{x_i-x_j\}\times\max\{y_i-y_j\}\}\)
根据小学奥数和一定差小积大,我们要最大化 \(|\max\{x_i-x_j\}-\max\{y_i-y_j\}|\)
分类讨论两种情况:
-
最小化 \(\max\{x_i-x_j\}\)
\(x=\{a_i|i\in[1,\ n]\}\)
-
最大化 \(\max\{x_i-x_j\}\)
此时 \(\max\{x_i-x_j\}=a_{2\times n}-a_1\)
需要最大化 \(\max\{y_i-y_j\}\) ,此时遍历一遍所有长度为 \(n\) 的连续区间即可
时间复杂度 \(O(n\log n)\)
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 10;
int n, a[maxn << 1];
int main() {
scanf("%d", &n);
for (int i = 1; i <= n << 1; i++) {
scanf("%d", a + i);
}
sort(a + 1, a + n + n + 1);
ll ans = 1ll * (a[n] - a[1]) * (a[n + n] - a[n + 1]);
for (int i = 1; i <= n; i++) {
ans = min(ans, 1ll * (a[n + n] - a[1]) * (a[n + i] - a[i + 1]));
}
printf("%I64d", ans);
return 0;
}