Language/C++

[c++][백준 21942][해시/파싱] 부품 대여장 - 컴도리돌이

컴도리돌이 2022. 3. 4. 18:00
728x90

 

 

21942번: 부품 대여장

첫 번째 줄에 부품 대여장에 작성된 정보의 개수 $N$, 대여기간 $L$, 벌금 $F$이 공백으로 구분되어 주어진다. 대여기간 형식은 DDD/hh:mm으로 DDD는 일, hh는 시간, mm은 분을 의미한다. (000/00:00 는 주어

www.acmicpc.net


해당 문제는 5번을 틀렸다.. 정말 제출하고 나서 실패라는 문구를 보면서 맞왜틀을 외쳤다.. 요번 문제는 풀이과정보다는 왜 틀렸는지를 언급하는 게 좋을 것 같다..

 

1. 너무 멍청했다. 빌리고 반납 기간이 최대 한 달이라는 안일한 생각을 했다. 2월에 빌리고 11월에 반납할 경우를 생각해보자. 나는 month라는 배열 값에 달의 일수를 입력하여 사용하였다. 그다음에 빌린 달과 반납하는 달의 차이가 한 달 이상일 경우 ( if(stoll(mm) - stoll(m) > 1) ) 반복문을 사용하여 해당 달의 일수를 더해줬다. 그다음에는 반납한 달의 일수 + 반복문 처리한 일수 + (빌린 달의 일수 - 빌린 날짜의 일수)로 최종 빌린 사람의 일수를 계산해줬다.

 

2. 이때부터 맞왜틀이었다. 2번째로 틀린 이유는 나는 해당 날짜를 모두 분으로 처리하였다. 그래서 반납 일수가 크고 벌금도 크면 int형으로 담을 수 없게 된다. 그래서 long long 형으로 바꿔줬다.

 

3. 마지막 진짜 이 부분이 중요하다. 해당 문제의 조건은 이렇다.

1. 한 사람이 같은 종류의 부품을 두개 이상 대여하고 있는 상태일 수 없다.
2. 한 사람이 같은 시각에 서로 다른 종류의 부품들을 대여하는 것이 가능하다.
3. 같은 사람이더라도, 대여 기간은 부품마다 별도로 적용된다.

나는 당연히 부품이라기에 빌린 수 있는 부품이 하나라고 안일하게 생각했다. 부품은 여러 개다.. 그렇기에 여러 사람이 하나의 부품을 빌릴 수 있다. 그래서 나는 (부품 + 빌린 사람 이름)으로 mapping을 시켜줬더니 바로 통과해버렸다... 후 좀 더 자세히 언급해줬으면 시간 낭비할 필요 없었을 텐데,,ㅠㅠ


#include<iostream>
#include<vector>
#include<string>
#include<map>
#include<algorithm>

using namespace std;

int month[] ={0,31,28,31,30,31,30,31,31,30,31,30,31};

struct info
{
    string mm;
    string dd;
    string time;
    string obj;
    string name;
    bool flag;
};

void init(){
    ios_base::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
}

long long feeCal(string m,string d,string t,string mm,string dd,string tt){

    long long t2 = stoll(tt.substr(0,2)) * 60 + stoll(tt.substr(3,2));
    long long t1 = stoll(t.substr(0,2)) * 60 + stoll(t.substr(3,2));
    if(m == mm){
        long long day = (stoll(dd) - stoll(d)) * 60 * 24;
        return day + (t2 -t1);
    }
    else{
        long long day = 0;
        if(stoll(mm) - stoll(m) > 1){

            for(long long i=stoll(m) + 1 ; i< stoll(mm); i++){
                day += (month[i] * 60 * 24);
            }
        }
        day += (stoll(dd) + (month[stoll(m)] - stoll(d))) * 60 * 24;
        return day + (t2 - t1);
    }
    
}

void solution(){
    long long n,f;
    string l;

    cin >> n >> l >> f;

    string day = l.substr(0,3);
    string hour = l.substr(4,2);
    string min = l.substr(7,2);

    long long reservedTime = (stoll(day) * 24 + stoll(hour)) * 60 + stoll(min);

    map<string,info> objInfo;
    map<string,long long> peopleFee;

    for(long long i=0; i<n; i++){
        string date,time,obj,name;
        cin >> date >> time >> obj >> name;

        string mm = date.substr(5,2);
        string dd = date.substr(8,2);

        if(objInfo[obj+name].flag){
            info i = objInfo[obj+name];
            long long used = feeCal(i.mm,i.dd,i.time,mm,dd,time);
            if(reservedTime < used){
                peopleFee[name] += (used - reservedTime) * f;
            }
            objInfo.erase(obj+name);
        }
        else{
            objInfo[obj+name] = {mm,dd,time,obj,name,true};
        }
    }
    if(peopleFee.empty()) 
    {
        cout << -1;
        return ;
    }
    vector<pair<string,long long>> v;
    for(auto p : peopleFee){
        v.push_back({p.first,p.second});
    }
    sort(v.begin(),v.end());
    for(auto vv : v){
        cout << vv.first << ' ' << vv.second << '\n';
    }
}

int main(){
    init();
    solution();
    return 0;
}

.