본문 바로가기
프로그래머스/C

[프로그래머스/C]프로그래머스 Level 2 : 주차 요금 계산 C언어

by starfish22 2022. 7. 2.
728x90

▶문제 : 코딩테스트 연습 - 주차 요금 계산 | 프로그래머스 (programmers.co.kr)

 

코딩테스트 연습 - 주차 요금 계산

[180, 5000, 10, 600] ["05:34 5961 IN", "06:00 0000 IN", "06:34 0000 OUT", "07:59 5961 OUT", "07:59 0148 IN", "18:59 0000 IN", "19:09 0148 OUT", "22:59 5961 IN", "23:00 5961 OUT"] [14600, 34400, 5000]

programmers.co.kr

 

▶코드 작성

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

int car[10000][2];  //[차량 확인,출입 유무]
int time[10000][3]; //[시,분,누적 시간(분)]

int toInteger(char *str, int start, int n) {//문자열을 숫자로 변환하는 함수
    int num = 0;
    str += start;//숫자로 바꾸려는 부분으로 포인터 조정
    for (int i = n - 1, ten = 1; i >= 0; i--, ten *= 10) {//뒷자리부터 차례대로 계산
        num += (str[i] - '0') * ten;//숫자로 바꿔준 후 자리수에 맞추기
    }
    return num;
}

int *solution(int fees[], size_t fees_len, const char *records[], size_t records_len) {
    // fees 0-기본시간 1-기본요금 2-단위시간 3-단위요금
    int h, m, num;
    int count = 0; //차량 수
    int max = 0;   //최대 차량 번호

	//----------차량 입차,출차와 누적 시간 계산----------
    for (int i = 0; i < records_len; i++) {
        h = toInteger(records[i], 0, 2);  //시
        m = toInteger(records[i], 3, 2);  //분
        num = toInteger(records[i], 6, 4);//차량 번호
        if (max < num) max = num; //최대 차량 번호 저장

        if (records[i][11] == 'I') {//"IN"일 때
            if (car[num][0] == 0) { //첫 출입일 때
                car[num][0] = 1;
                count++;
            }
            car[num][1] = 1;//입차
            time[num][0] = h;
            time[num][1] = m;
        }
        else {//"OUT"일 때
            car[num][1] = 0;//출차
            if (time[num][0] == h) {//'시'가 같다면 '분'만 계산
                time[num][2] += m - time[num][1];//누적 시간에 추가
            }
            else {//'시'가 다를 때
                time[num][2] += (60 - time[num][1]) + (h - (time[num][0] + 1)) * 60 + m;
            }
        }
    }

	//----------차량 요금 계산----------
    int *answer = (int *)malloc(count * sizeof(int));//차량 수 만큼 동적할당
    int len = 0;

    for (int i = 0; i <= max; i++) {//최대 차량 번호만큼 반복
        if (car[i][1] == 1) {//출차를 하지 않은 차량 누적시간 계산
            time[i][2] += (59 - time[i][1]) + (24 - (time[i][0] + 1)) * 60;
        }
        if (car[i][0] == 1) {//i번의 차량이 있다면
            if (time[i][2] <= fees[0]) {//기본시간 이하라면 기본요금
                answer[len++] = fees[1];
            }
            else {//기본시간 초과시
                double d = (double)(time[i][2] - fees[0]) / fees[2];
                if (d > (int)d) d = (int)d + 1;//딱 떨어지지 않으면 올림
                answer[len++] = fees[1] + d * fees[3];
            }
        }
    }

    return answer;
}

 

▶해석

배열이 필요한 부분이 총 5가지라고 생각했는데 차량 번호, 차량 출입 유무, 입차했을 때 시와 분, 누적시간이다.

마지막에 요금을 매길 때 차량 번호순으로 반환해야 하므로 쉽게 순서를 알 수 있도록 배열 자리를 차량 번호로 하였다.

car [차량 번호][0] : 차량 번호의 차가 있는지 확인 용도 있으면 1, 없으면 0

car [차량 번호][1] : 차량의 입차, 출차 확인 용도 입차 1, 출차 0

시, 분, 누적 시간은 하나의 배열로 만들었다.

time [차량 번호][0] : 시 , time [차량 번호][1] : 분 , time [차량 번호][2] : 누적시간

 

코드를 크게 두 부분으로 차량 입차, 출차, 누적시간을 계산하는 for문과 요금을 계산하는 for문으로 나눌 수 있다.

먼저 차량 입차, 출차, 누적시간을 계산하는 for문부터 보자면

toInteger함수를 사용해 문자열인 시, 분, 차량 번호를 숫자로 바꿔주었다.

 

toInteger함수는 포인터 str에 문자열 주소, 얻으려는 문자열의 시작점을 start에 입력, 문자의 개수를 n에 입력한다.

포인터에 start를 더하여 구하려는 문자열 자리로 조정하고, n만큼 반복하여 자릿수에 맞게 숫자로 바꿔준다.

 

다시 돌아가 차량이 "IN"일 때와 "OUT"일 때를 구분한다.

먼저 "IN"일 때 첫 출입인지 확인한 후 '시'와 '분'을 저장한다.

"OUT"일 때는 '시'가 같을 때와 다를 때를 구분하여 주차한 시간을 계산해 누적시간에 더해준다.

 

다음은 차량 요금 계산 부분으로 넘어가 for문으로 차량 번호의 최댓값만큼 반복한다.

요금을 계산하기 전에 입차는 했지만 출차를 안 한 차량을 확인하여 23:59까지로 주차시간을 계산하였다.

i값이 차량 번호이고 car [i][0] 값이 1일 때 차량이 들어온 적이 있다는 의미이다.

누적시간을 확인하여 기본시간 이하라면 기본요금, 이상이라면 추가 요금을 계산하였다.

추가요금 계산은 딱 나눠 떨어지는지 알아야 하므로 double형으로 계산한다.

계산한 값인 d를 if문으로 d와 (int) d를 비교한다.

왜냐하면 int형으로 형 변환시키면 내림으로 되기 때문에 double형인 d가 int형인 d보다 크다면 소수점이 있다는 것이다.

따라서 소수점이 있다면 올림 해주어 기본요금에 추가 요금을 더해 계산해준다.

728x90

댓글