CF1012A Photo of The Sky

\(\verb|CF1012A Photo of The Sky|\)

\(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;
}

猜你喜欢

转载自www.cnblogs.com/Juanzhang/p/10627894.html
sky
今日推荐