2n개의 수 {a1,a2,,,,a2n}이 주어졌을 때 n개의 좌표쌍을 고르고 이 좌표들을 덮을 수 있는 가장 작은 사각형의 넓이를 구하는 문제다.
동일한 위치의 좌표가 여러개일 수 있다.
i번째 수를 x좌표로 골랐다고 생각해 보자. 사각형은 이 점을 반드시 덮어야 한다.
사각형의 왼쪽 아래 점을 (x1,y1) 오른쪽 위 점을 (x2,y2)라고 할 때 x1<=ai<=x2여야 한다.
결국 n개의 좌표쌍을 골랐을 때 사각형의 윗면은 max_x, 아랫면은 min_x가 되고
왼쪽은 min_y, 오른쪽은 max_y가 되므로 사각형의 넓이는 (max_x - min_x) * (max_y - min_y)가 된다.
선택을 쉽게하기 위해서 일단 정렬을 한다.
이제부터 x좌표를 n개 고를건데 이걸 네가지로 분류해 보자
1. x좌표의 최소값이 a[0], 최대값이 a[i] (i!=2*n-1)일 경우
최소값과 최대값 사이에서 n개를 고를 수 있어야 하므로 i>=n-1을 만족해야 한다.
또한 나머지 값들이 y좌표값이 되므로 y의 최소값은 a[j] (j!=0), 최대값은 a[2*n-1]이 되고 j<=n을 만족해야 한다.
정렬이 되어 있으므로 (a[i] - a[0]) * (a[2*n-1] - a[j])의 최소값은 i==n-1, j==n일때 나온다. O(1)
2. x좌표의 최소값이 a[i] (i!=0), 최대값이 a[2*n-1]일 경우
여기서 x좌표값이 아니라 y좌표값을 a[i]~a[2*n-1]에서 고른다고 생각하면 1번의 경우와 완전히 일치한다. 따라서 구할 필요가 없다.
3. x좌표의 최소값이 a[i] (i!=0), 최대값이 a[j] (j!=2*n-1)일 경우
i~j사이에서 n개를 고를 수 있어야 하므로 j-i+1>=n을 만족해야 한다.
또한 x좌표를 저렇게 골랐으므로 y좌표는 a[0], a[2*n-1]을 무조건 포함한다. 따라서 사각형의 넓이는
(a[2*n-1] - a[0]) * (a[j] - a[i])가 되고 a[j]-a[i]는 j == n+i-1일 때 최소값이 된다. O(n)
4. x좌표의 최소값이 a[0], 최대값이 a[2*n-1]일 경우
2번의 경우와 마찬가지로 x를 y로 생각해보면 3번과 동일하다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #include <stdio.h> #include <algorithm> using namespace std; int n; long long a[200001], ans; int main() { scanf("%d", &n); for (int i = 0; i < 2*n; ++i) scanf("%lld", a + i); sort(a, a + 2 * n); ans = (a[2 * n - 1] - a[n])*(a[n - 1] - a[0]); for (int i = 1; i < n; ++i) ans = min(ans, (a[i + n - 1] - a[i])*(a[2 * n - 1] - a[0])); printf("%lld", ans); return 0; } | cs |
'codeforces > #500 div2' 카테고리의 다른 글
B. And (0) | 2018.08.02 |
---|---|
A. Piles With Stones (0) | 2018.08.02 |