쌓고 쌓다

[프로그래머스] 주차 요금 계산 C++ 풀이 본문

알고리즘/프로그래머스

[프로그래머스] 주차 요금 계산 C++ 풀이

승민아 2022. 12. 31. 17:30

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

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

전체 코드

#include <string>
#include <vector>
#include <map>
#include <iostream>
using namespace std;

vector<int> solution(vector<int> fees, vector<string> records) {
    vector<int> answer;
    // fess : 기본시간(분), 기본요금(원), 단위시간(분), 단위 요금(원)
    // records : 시각, 차량번호, 내역
    map<string, int> total_m; // 차량번호, 총시간(분)
    map<string, string> in_m; // 차량번호, 입차시간
    // map은 기본적으로 key값을 오름차순으로 정렬되어있다.
    
    for(int i=0; i<records.size(); i++)
    {
        string data[3]; // 공백을 기준으로 문자열을 끊어 넣을것임
        int data_i=0; // data[0], 1, 2 각각 차례대로 시각, 번호, 입출차 정보를 저장
        for(int idx=0; idx<records[i].length(); idx++)
        {
            if(records[i][idx]==' ') // 공백을 만난다면 다음 정보를 저장
                data_i++;
            else if(records[i][idx]!=':') // 시각에 :는 안넣을것임.
                data[data_i]+=records[i][idx];
        }
        
        if(data[2]=="IN"){ // 입차
            in_m.insert({data[1], data[0]}); // 차량번호, 입차시간 삽입
        }
        else if(data[2]=="OUT"){ //출차
            string in_clock = in_m.find(data[1])->second; // 해당 차량의 입차시간
            string in_minute, out_minute; // 입출차 분단위는 따로 관리. 예외를 위함.(07:02,09:01)
            in_minute += in_clock[2];
            in_minute += in_clock[3];
            out_minute += data[0][2];
            out_minute += data[0][3];
            
            if(total_m.find(data[1])==total_m.end()) // 입출차 정산 기록이 없다면 총시간 0으로 초기화
                total_m.insert({data[1], 0});
            
            // 주차한 총시간 계산
            total_m.find(data[1])->second += (data[0][0]-in_clock[0])*600; // 십시간 단위 계산
            total_m.find(data[1])->second += (data[0][1]-in_clock[1])*60; // 한자리시간 계산
            
            // 분단위 계산
            if(stoi(in_minute)>stoi(out_minute)){ // 예외(IN:07:02, OUT:08:01)
                total_m.find(data[1])->second -= stoi(in_minute) - stoi(out_minute);
            } else { // 분을 비교했더니 출차가 더 큰 경우 간단히 빼주면 계산됨. 왜냐 시간은 오름차순으로 주어지기 때문에 시각은 신경 안써도 된다.
                total_m.find(data[1])->second += stoi(out_minute) - stoi(in_minute);
            }
            
            in_m.erase(data[1]); // 입차기록 삭제
        }
    }
    
    /* 출차 내역이 없는 데이터 처리 */
    map<string, string>::iterator it; 
    for(it=in_m.begin(); it!=in_m.end(); it++)
    {
        string in_clock = it->second;
        string in_minute;
        in_minute += in_clock[2];
        in_minute += in_clock[3];
        if(total_m.find(it->first)==total_m.end()) // 입출차 정산 기록이 없다면 총시간 0으로 초기화
            total_m.insert({it->first, 0});
        
        // '2','3'은 출차 기록이 없는 경우 23:59를 기준으로하기 때문.
        total_m.find(it->first)->second += ('2'-in_clock[0])*600;
        total_m.find(it->first)->second += ('3'-in_clock[1])*60;
        total_m.find(it->first)->second += 59-stoi(in_minute);
        in_m.erase(it->first);
    }
    
    /* 요금 정산 */
    for(map<string, int>::iterator it=total_m.begin(); it!=total_m.end(); it++)
    {
        int fee=0;
        int total = it->second;
        if(total <= fees[0]){ // 기본시간보다 작으면 기본요금 부과
            fee=fees[1];
        }else{
            total -= fees[0];
            fee+=fees[1];
            if(total%fees[2]!=0) // 단위시간으로 나누어 떨어지지 않으면
                fee+=fees[3]+(total/fees[2])*fees[3]; // 기본 요금을 한번더 더해주어 올림을 함.
            else
                fee+=(total/fees[2])*fees[3];
        }
        
        answer.push_back(fee);
    }
    
    return answer;
}

입출차 분단위는 따로 저장하는 이유는

시간 단위는 주어질때 오름차순으로 주어지기에 무조건 OUT이 IN보다 크거나 같다.

하지만 분단위는 작을수도 클수도 같을수도 있기 때문이다.

 

Comments