https://codeforces.com/problemset/problem/1252/H
바로 전에 포스팅한 문제의 풀이와 유사
<문제설명>
L*W로 표현되는 영역들이 주어진다. (L,W<=1e9) 이 영역들에 두 개의 A*B크기의 빌딩을 지으려고 한다. 빌딩 넓이의 최댓값을 구하라. (한 영역에 두 빌딩을 다 지어도 된다)
<풀이>
하나의 영역에 두 빌딩을 다 짓는 경우와 두 영역에 나눠 짓는 경우로 나눠 풀었다.
(하나의 영역에 두 빌딩을 다 짓는 경우는 쉬우니까 생략)
한 영역에 하나씩 빌딩을 두 개 지을 때 지을 수 있는 빌딩 크기의 최댓값은 어떻게 구할까?
i번 영역과 j번 영역에 빌딩을 짓는다면,
min(Li, Lj) * min(Wi, Wj)가 지을 수 있는 빌딩의 최대 크기일 것이다.
영역을 90도씩 돌려가며 생각해도 문제의 일반성을 해치지 않으므로, Li<=Wi를 강제해서 입력받는다.
그 후 Li크기를 기준으로 오름차순으로 정렬한다
i번째 영역에 빌딩을 지을때 최댓값을 갱신해가면 된다.
ans = max(ans, a[i].fisrt * min(a[i].second, sf[i + 1]));
앞선 포스팅의 그림처럼 그리면 형태가 바로 눈에 들어올 것.
<코드>
int n;
ll sf[MAX], ans, temp;
P a[MAX];
int main() {
FAST; cin >> n;
for (int i = 0; i < n; i++) {
ll l, w; cin >> l >> w;
if (l > w) swap(l, w);
a[i] = { l,w };
temp = max(temp, l * w);
temp = max(temp, l * w);
}
sort(a, a + n);
for (int i = n - 1; i >= 0; i--)
sf[i] = max(sf[i + 1], a[i].second);
for (int i = 0; i < n; i++) {
ll l, w;
tie(l, w) = a[i];
ans = max(ans, l * min(w, sf[i + 1]));
}
if (ans * 2 >= temp) cout << ans << ".0\n";
else cout << temp / 2 << "." << (temp % 2 ? 5 : 0) << '\n';
}
<생각>
double은 유효숫자가 15자리이므로, 1e15를 넘어가는 값에 대한 연산은 loss가 너무 크다.
최대 1e18에 대해 연산해야 하므로 double을 쓰면 안된 다는 점 유념
'알고리즘 > 코드포스' 카테고리의 다른 글
cf #656 div3 E - Directing Edges(위상정렬, 사이클 유무) (0) | 2020.07.20 |
---|---|
cf #653 div3 F - Cyclic Shifts Sorting (그리디, constructive, sorting, inversion) (0) | 2020.07.13 |
cf #621 div1&2 D - Cow and Fields (그리디, 정렬, 그래프) (0) | 2020.04.17 |
cf #632 div2 C - Eugene and an array (투포인터) (0) | 2020.04.13 |
cf #538 div2 C - Trailing Loves (소인수분해, 수학) (0) | 2020.04.02 |