1. 문제 설명
2. 아이디어
이 문제를 모자마자 떠올린 방법은 지면부터 가장 위의 수조 상단부까지를 잘게 쪼개는 것이었다.
시간 복잡도에 걸리지는 않을까? 걱정을 했었는데
처음 입력받을 때부터 바닥을 인덱스 0으로 잡고 해당 인덱스에 존재하는 수조의 용량을 계산한다.
그러면 이후 해결 단계에서는 입력된 정보를 1번 인덱스부터 물을 채워보면 된다.
물을 채운다는 의미는 곧 처음 주어진 물의 양이 현재 인덱스의 수조 부피만큼 소모되었음을 의미하므로
입력받은 물의 부피를 계속해서 차감한다.
문제는 이 물의 부피가 0이 아니라 음수값이 나왔을 때를 처리해주어야 하므로
한 단계 이전으로 작업을 되돌리고 반복문을 빠져나와 소수점 계산을 처리해주면 된다.
이건 사실 C++을 소수점 처리를 어떻게 처리하는지 몰라서 찾아보고 해결했다. ㅎㅎㅎ..
로직 자체는 플래티넘치고 쉬운 편이었다.
3. 코드
#include <iostream>
#include <vector>
#include <algorithm>
#include <tuple>
#define endl "\n"
#define INF 1040002
using namespace std;
int n, v;
int capacity[INF];
void input_value() {
cin >> n;
for (int i=0; i<n; i++) {
int b, h, w, d; cin >> b >> h >> w >> d;
int a = w * d;
for (int i=0; i < h; i++) {
capacity[b] += a;
b++;
}
}
cin >> v;
}
void solution() {
int area=0, idx=1;
bool flag = false;
for (idx; idx < INF; idx++) {
//cout << idx << " : " << capacity[idx-1] << ", v = " << v << endl;
area = capacity[idx-1];
v -= area;
if (v == 0) { // 딱 맞게 떨어지면 출력하고 종료
cout << idx << ".00" << endl;
return;
} else if (v < 0) { // for문 break하고 남은 잔여량 소수점 계산
v += area;
idx--;
flag = true;
break;
}
}
if (!flag) { cout << "OVERFLOW" << endl; return;} // for문이 닫혔는데 flag가 false다? == 수조 부피가 V보다 작았다.
cout << fixed; cout.precision(2);
cout << (double)idx + v/(double)area << endl;
return;
}
int main() {
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
input_value();
solution();
return 0;
}