Coding Test/Solution

[C++] 2130 - 수조 (플래티넘5)

나죽못고나강뿐 2022. 8. 6. 14:11

1. 문제 설명

 

 

2130번: 수조

N(1≤N≤50,000)개의 수조가 있다. 각각의 수조는 3차원 공간상에 존재한다. 수조에 대한 정보는 수조가 위치한 높이 b(0≤b≤1,000,000), 수조 자체의 높이 h(1≤h≤40,000), 수조의 가로길이 w(1≤w≤40,000)

www.acmicpc.net

 


2. 아이디어

 

이 문제를 모자마자 떠올린 방법은 지면부터 가장 위의 수조 상단부까지를 잘게 쪼개는 것이었다.

시간 복잡도에 걸리지는 않을까? 걱정을 했었는데

아 ㅋㅋㅋㅋ 이 맛에 C++ 쓴다. 너무 빨라~~

처음 입력받을 때부터 바닥을 인덱스 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;
}