알고리즘/프로그래머스 2단계

프로그래머스 - 주차 요금 계산 - C++

게임만드는학생 2024. 8. 8. 14:17

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

 

프로그래머스

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

programmers.co.kr

 

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

vector<int> solution(vector<int> fees, vector<string> records) {
    vector<int> answer;
    map<string,bool> states;// in인지 out인지
    map<string,int> times;// 누적시간
    map<string, int> curTime;// in이라면 몇시에 in했는지
    int maxTime = 1439;
    
    for(int i=0;i<records.size();i++)
    {
        string time = records[i].substr(0,5);
        string id = records[i].substr(6,4);
        string state = records[i].substr(11);
        
        if(state=="IN")
        {
            states[id]=true;
            int t=stoi(time.substr(0,2))*60 + stoi(time.substr(3));
            curTime[id]=t;
            if(times.find(id)==times.end())
                times[id]=0;
        }
        else
        {
            states[id]=false;
            int t = stoi(time.substr(0,2))*60 + stoi(time.substr(3)) - curTime[id];
            times[id] += t;
        }
    }
    
    for(auto& item : times)
    {
        // 출차되지 않은차
        if(states[item.first])
            times[item.first]+=maxTime - curTime[item.first];
        
        int sum = fees[1];
        if(times[item.first]>fees[0])
        {
            int it;
            if(((times[item.first]-fees[0])%fees[2])==0)
                it = ((times[item.first]-fees[0])/fees[2]);
            else
                it = ((times[item.first]-fees[0])/fees[2])+1;
            sum+= it * fees[3];
        }
        answer.push_back(sum);
    }
    
    return answer;
}

주어진 요금 기준과 입출차 기록을 분석해서 각 차량이 얼만큼의 요금을 정산해야하는지를 리턴하는 문제이다. 

 

번호가 작은순서대로 정렬해야하기 때문에 map을 사용한다. 

번호를 key로 하는 3개의 map을 생성한다. 

입출차상태, 총 누적시간, 입차라면 몇시에 입차했는지를 각각 나타낸다. 

 

string time = records[i].substr(0,5);
        string id = records[i].substr(6,4);
        string state = records[i].substr(11);

먼저 주어진 기록을 3개의 변수로 나눈다. 

 

if(state=="IN")
        {
            states[id]=true;
            int t=stoi(time.substr(0,2))*60 + stoi(time.substr(3));
            curTime[id]=t;
            if(times.find(id)==times.end())
                times[id]=0;
        }
        else
        {
            states[id]=false;
            int t = stoi(time.substr(0,2))*60 + stoi(time.substr(3)) - curTime[id];
            times[id] += t;
        }

그리고 IN이라면 입차라는 뜻으로 states[id]에 true로 표시한다. 

또 현재 시각을 분단위로 환산하여 curTime[id]에 저장한다. 

마지막으로 처음 입차라면 times에 0을 저장한다. 아니라면 이미 누적기록이 있기떄문에 놔둔다. 

 

Out이라면 false로 바꾸고 현재시각에서 이전 입차때의 시각인 curTime[id]를 빼서 times에 누적한다. 

 

for(auto& item : times)
    {
        // 출차되지 않은차
        if(states[item.first])
            times[item.first]+=maxTime - curTime[item.first];
        
        int sum = fees[1];
        if(times[item.first]>fees[0])
        {
            int it;
            if(((times[item.first]-fees[0])%fees[2])==0)
                it = ((times[item.first]-fees[0])/fees[2]);
            else
                it = ((times[item.first]-fees[0])/fees[2])+1;
            sum+= it * fees[3];
        }
        answer.push_back(sum);
    }

작은 번호순서대로 새로 for문을 돌며 끝까지 출차되지 않은 차에 대해서 23:59분에 출차한 것으로 처리해 time에 누적한다. 

 

그리고 정산을 시작한다. 기본요금을 초기값으로 기본시간을 넘겼으면 sum에 추가하여 answer에 추가한다. 

이 때, if - else 문은 조건 중, 나누어 떨어지지 않으면 올림하라는 조건이 있기 때문이다. 

 

문제를 잘 보지않아서 이 올림하라는 조건을 못적어서 한참 해맸다. 또 시간 * 60을 해야하는데 *24를 해서 또 한참 해맸다. 

vs로 디버깅 하면서 깨달았다.