Coding Interview/프로그래머스

[C++] 프로그래머스 주차요금계산 - 성공했으나 효율적이지 않음.

2로 접어듦 2023. 1. 20. 21:00

문제

https://school.programmers.co.kr/learn/courses/30/lessons/92341

 

리뷰

차량 번호와 소요시간을 계산해서, 주어진 공식에 맞게 계산한 값을 차량번호가 작은 순서대로 리턴하면 된다.

 

"들어갔다 나가지 않았다면" 을 보다 간단하게 "기록이 홀수 개라면" 이라고 조건을 생각할 수 있을 것이고,
(굳이 map을 만들어 false, true로 구분할 필요는 없다)

주차한 시간에 대한 계산은 hour min 구분은 필요 없으므로 min 단위로 바꿔 계산하면 편할 것이며,

(굳이 min이 작은 경우 hour에서 1을 빼고... 하는 사람이 하는 계산 처럼 구현할 필요는 없다)

차량번호가 작은 순서대로 리턴하는 것은 차량 번호를 int로 하는 vector를 선언해서 하면 된다.
(굳이 <차량번호, 시간>을 맵으로 만들어 sort할 필요는 없다. 중복이 없는데 왜 map을 만드는가?)

 

코드

보다 효율적인 코드는 '다른사람풀이'의 맨 처음 코드를 참고했다.

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

using namespace std;

int CalTotalTime(string in, string out){
    string ihs = ""; ihs+=in[0]; ihs+=in[1];
    string ims = ""; ims+=in[3]; ims+=in[4];
    int ihour = stoi(ihs), imin = stoi(ims);

    string ohs = ""; ohs+=out[0]; ohs+=out[1];
    string oms = ""; oms+=out[3]; oms+=out[4];
    int ohour = stoi(ohs), omin = stoi(oms);

    int total = 0;
    if(omin >= imin){
        total += (omin-imin);
        total += (ohour-ihour)*60;
    }
    else{
        total += (60-imin + omin);
        total += (ohour-1-ihour) * 60;
    }
    
    return total;
}

bool comp(pair<string, int> a, pair<string, int> b){
    return a.first < b.first;
}

int time_convert(string& time){
    int result;
    int h = (time[0]-'0') * 10 + (time[1]-'0');
    int m = (time[3]-'0') * 10 + (time[4]-'0');
    
    result = h*60 + m;    
    return result;
}

vector<int> solution(vector<int> fees, vector<string> records) {
    vector<int> answer;
    
    // 방법 2 - 보다 효율적인 코드
    vector<vector<int>> car_with_time(10001, vector<int>());
    string time, car_num, in_or_out;
    
    for(auto &str : records){
        stringstream str1(str);
        str1 >> time >> car_num >> in_or_out;
        
        car_with_time[stoi(car_num)].push_back(time_convert(time));
    }
    
    for(int i=0; i<10000; i++){
        if(!car_with_time[i].empty()){
            if(car_with_time[i].size() % 2 != 0)
                car_with_time[i].push_back(23*60 +59);
            
            int sum = 0;
            for(int j=1; j<car_with_time[i].size(); j+=2)        // (들어온시간)(나간시간)(들어온시간)(나간시간)
                sum += car_with_time[i][j] - car_with_time[i][j-1];
            
            int bill = fees[1];
            if(sum > fees[0])
                bill += (ceil((double)(sum - fees[0])/fees[2]) * fees[3]);
            
            answer.push_back(bill);
        }
    }
    
    /*
    // 방법 1
    map<string, int> total_parking_time;
    map<string, string> record_in_time;
    map<string, bool> whether_out;          // false = out 기록이 없음
    
    for(auto &str : records){
        // 1. 입 - 출 기록
        stringstream str1(str);
        string time, car_num, in_or_out;
        str1 >> time >> car_num >> in_or_out;
        
        if(in_or_out == "IN"){
            whether_out[car_num] = false;
            record_in_time[car_num] = time;
            continue;
        }
        if(in_or_out == "OUT"){
            whether_out[car_num] = true;
            // 2. 소요시간 계산
            
            int total = CalTotalTime(record_in_time[car_num], time);
            
            total_parking_time[car_num] += total;
        }
    }
    for(auto out_check : whether_out){
        if(out_check.second == false){
            int total = CalTotalTime(record_in_time[out_check.first], "23:59");
            
            total_parking_time[out_check.first] += total;
        }
    }
    
    // 3. 요금 계산
    map<string, int> total_fee;
    for(auto fee=total_parking_time.begin(); fee!=total_parking_time.end(); fee++){
        int result;
        if(fee->second <= fees[0]){
            result = fees[1];
            total_fee[fee->first] = result;
            continue;
        }
        
        result = fees[1];
        double m = (fee->second - fees[0]) / fees[2];
        int n = ceil((double)(fee->second - fees[0]) / fees[2]);
        result += (ceil((double)(fee->second - fees[0])/fees[2]) * fees[3]);
        cout << n << '\n';
        
        total_fee[fee->first] = result;
    }
    
    vector<pair<string, int>> for_sort(total_fee.begin(), total_fee.end());
    sort(for_sort.begin(), for_sort.end(), comp);
    
    for(int i=0; i<for_sort.size(); i++)
        answer.push_back(for_sort[i].second);
    
    */
    
    return answer;
}