일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- MST
- 백준
- 위상정렬
- lis
- 세그먼트트리
- 이분매칭
- 삼분탐색
- 에라토스테네스의 체
- 플로이드와샬
- dfs
- 이진탐색
- 비트마스크
- 펜윅트리
- lca
- 이분탐색
- 브루트포스
- LazyPropagation
- boj
- 그리디
- 투포인터
- 크루스칼
- DisjointSet
- 누적합
- 좌표압축
- 정렬
- BFS
- 다익스트라
- 수학
- DP
- 구현
Archives
- Today
- Total
lastknight00
[백준] 수조(1)(2130) 본문
문제 링크 : [백준] 수조(1)(2130)
문제 설명
문제 설명이 어려우니 링크 참조 해주세요.
입력
N(수조의 갯수,1<=N<=50,000)
Bi(수조가 위치한 높이,0<=Bi<=1,000,000)
Hi(수조 자체의 높이,1<=Hi<=40,000)
Wi(수조의 가로 길이,1<=Wi<=40,000)
Di(수조의 세로 길이,1<=Di<=40,000)
V(물의 부피,1<=2,000,000,000)
4
11 7 5 1
15 6 4 1
5 8 5 1
19 4 8 1
78
출력
수면의 높이
17.00
카테고리
#스위핑
시간 복잡도 상한
W,D는 수조의 면적을 구하기 위한 것으로 문제를 푸는 시간 복잡도에는 영향을 주지 않을 것 같습니다.
밑면부터 수조의 꼭대기가 위치할 수 있는 최대 높이까지 각 높이별로 물의 부피를 구한다면,
1,040,000 * 50,000 이므로 TLE가 됩니다.
대략 O(Nlog(B+H)) 정도가 상한이 될 것 같습니다.
해결 방법
- 각 높이별로 수조에 얼마나 물이 차는지 확인을 할 수 있지만, N이 5만이기 때문에, 높이별로 각각의 수조에 대해 부피를 구한다면 TLE이 됩니다.
- 그렇다면 우리가 모든 높이별로 모든 수조를 매번 구할 필요가 있는지 생각해봅니다.
- 모든 수조는 자신의 바닥 높이보다 크고, 자신의 꼭대기 높이보다 낮은 부분에서는 높이가 높아질 수록, 자신의 밑넓이 * (물의 높이-자신의 바닥의 높이) 만큼의 물을 담을 수 있습니다.
- 그렇다면 높이를 인덱스로하는 1차원 배열에 아래와 같은 작업을 해줍니다.
4-1. 자신의 바닥높이에 +밑바닥 넓이
4-2. 자신의 꼭대기 높이에 -밑바닥 넓이 - 눈치채신분들도 계시겠지만, 스위핑을 하기 위한 밑작업을 하여, 수면을 1~마지막까지 각 높이별로 훑으면서 각 높이별로 물의 부피를 누적합으로 구하면 됩니다.
- 단 우리는 소수점 두자리까지 구해야 합니다.
- 아래와 같은 방법으로 소수점 두자리까지 구하여 출력해주면 됩니다.
7-1. 현재 높이까지의 물의 부피가 구하고자 하는 부피와 같다면 소수점 아래 값은 0이됩니다.
7-2. 그렇지 않다면 소수점을 구해야합니다.
7-3. 현재 남은 물의 부피 * 10 / 현재 확보된 밑면의 넓이를 해주면, 소수점 첫째 자리를 구할 수 있습니다.
7-4. 마찬가지로, 7-3을 한번 더 하면, 소수점 둘째자리까지 구할 수 있으나, 셋째 자리에서 반올림 해야되기 때문에, 남은 수가 5보다 작은지를 확인하여 소수 둘째자리수를 보정해줍니다.
시간복잡도
O(H+N)
코드
#include<cstdio>
#define MAX 1040005
int cap[MAX];
int b, x, y, h, s, v, N, i, j, k;
bool ex;
int main() {
scanf("%d", &N);
for(i = 0; i < N; i++) {
scanf("%d %d %d %d", &b, &h, &x, &y);
v = x * y;
cap[b] += v;
cap[b + h] -= v;
}
scanf("%d", &v);
for(i = 1; i < MAX; i++) {
s += cap[i - 1];
v -= s;
if(v == 0) {
printf("%d.00", i);
return 0;
}
else if(v < 0) {
v += s;
i--;
ex = true;
break;
}
}
if(!ex) {
printf("OVERFLOW");
return 0;
}
v *= 10;
j = v / s;
v = (v % s) * 10;
if(v == 0) {
printf("%d.%d", i, j);
return 0;
}
k = v / s;
v = (v % s) * 10;
if(v == 0) {
printf("%d.%d%d", i, j, k);
return 0;
}
if(s * 5 <= v) {
k++;
if(k == 10) {
k = 0;
j++;
if(j == 10) {
j = 0;
i++;
}
}
}
printf("%d.%d%d\n", i, j, k);
}
'PS' 카테고리의 다른 글
[백준] 열차정렬(4198) (0) | 2020.06.02 |
---|---|
[백준] 수조(2)(2130) (0) | 2020.06.01 |
[백준] 행렬 곱셈 순서(11049) (0) | 2020.06.01 |
[백준] 외판원 순회(2098) (0) | 2020.05.31 |
[백준] 순열복원(1777) (0) | 2020.05.31 |
Comments