2979번 트럭 주차 문제
문제의 요지는 주차된 차량 별 3가지 요금을 입력 받아서,주차된 차량이 몇 대냐에 따라 1대 당 요금을 다르게 책정하고최종적으로 발생하는 비용을 물어보는 문제였다.
먼저 무작정 풀어보기
값을 입력 받고, for문의 범위를 정하기 위해 최대 / 최소를 구하는 로직
int A, B, C;
cin >> A >> B >> C;
int arr[3][2] = {};
int min = 101, max = -1;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 2; j++)
{
cin >> arr[i][j];
if (arr[i][j] >= max)
max = arr[i][j];
if (arr[i][j] <= min)
min = arr[i][j];
// 아래 for문의 범위를 정하기 위해 max / min 값을 가져옴
}
}
- 범위를 정하기 위해 최소 / 최대 값을 가져왔다.
주차된 트럭 대수를 체크하고 주차비용을 계산하는 로직
bool checkTruck[3] = { false, false, false };
for (int i = min; i < max; i++)
{
if (i == arr[0][0])
checkTruck[0] = true;
if (i == arr[1][0])
checkTruck[1] = true;
if (i == arr[2][0])
checkTruck[2] = true;
if (i == arr[0][1])
checkTruck[0] = false;
if (i == arr[1][1])
checkTruck[1] = false;
if (i == arr[2][1])
checkTruck[2] = false;
// i번째 트럭이 오면 on
// i번째 트럭이 떠나면 off
int sum = 0;
// 그리고 총 몇 대가 주차되어 있는지 확인하고, 트럭 대수에 따라 sum에 누적
switch (checkTruck[0] + checkTruck[1] + checkTruck[2])
{
case 0:
break;
case 1:
sum += A;
break;
case 2:
sum += 2 * B;
break;
case 3:
sum += 3 * C;
break;
}
}
- 2차원 배열의 0번째 값에 도착 시간, 2차원 배열의 1번째 값에 떠난 시간을 넣어서 시간에 따라 계산될 수 있도록 했다.
- bool 값을 이용해서 총 몇 대가 주차되었는지 확인하고 그 수에 따라 누적시켰다.
전체 코드
#include <iostream>
using namespace std;
int main()
{
int A, B, C;
cin >> A >> B >> C;
int sum = 0;
int arr[3][2] = {};
int min = 101, max = -1;
bool checkTruck[3] = { false, false, false };
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 2; j++)
{
cin >> arr[i][j];
if (arr[i][j] >= max)
max = arr[i][j];
if (arr[i][j] <= min)
min = arr[i][j];
}
}
for (int i = min; i < max; i++)
{
if (i == arr[0][0])
checkTruck[0] = true;
if (i == arr[1][0])
checkTruck[1] = true;
if (i == arr[2][0])
checkTruck[2] = true;
if (i == arr[0][1])
checkTruck[0] = false;
if (i == arr[1][1])
checkTruck[1] = false;
if (i == arr[2][1])
checkTruck[2] = false;
switch (checkTruck[0] + checkTruck[1] + checkTruck[2])
{
case 0:
break;
case 1:
sum += A;
break;
case 2:
sum += 2 * B;
break;
case 3:
sum += 3 * C;
break;
}
}
cout << sum << endl;
}
정답!...!?
- 코드가 많이 길어지고 가독성이 떨어지긴 하지만 결국 풀렸다.
- 하지만 분명 더 좋은 방법이 있을 것 같다..ㅎㅎ
카운팅 배열의 개념
- 카운팅 배열은 특정한 규칙에 의해 구간마다 누적되는 값을 담아놓은 배열이라고 이해했다.
- 예를 들어 트럭 예제의 경우를 예로 들면 1 6이라는 입력이 있고 3 5라는 입력이 있으면
- 필요한 만큼의 0으로 초기화된 배열을 만들고, 처음에는 1 2 3 4 5번 인덱스에 1을 더해준다.(1 6 구간)
- 그리고 3 5 입력에 대해서 3 4번 인덱스에 다시 1을 더해준다.
- 이로써 3분 4분 구간에는 트럭이 2대 주차되어 있었다는 얘기가 된다.
- 지나간 시간을 재는 경우 트럭이 동시에 있었다고 해서 그 시간을 계산하는 것을
- 꼭 동시에 재야 하는게 아니라는걸 느끼게 됐다.
위에 내가 짠 코드의 문제점은 for문안에 모든 연산을 집어넣고 시간대마다 트럭이 몇 대인지
그 순간 순간에 다 측정하려는 내 성급함이 문제였던 것 같다.
1대가 먼저 와서 1시에서 6시까지 있었고~ 다시 다른 1대가 와서 3시부터 5시까지 있었으니~
이런 식으로 천천히 생각할 필요성을 느꼈다.
카운팅 배열로 다시 짠 코드
#include <iostream>
using namespace std;
int main()
{
int A, B, C;
cin >> A >> B >> C;
int sum = 0;
int arr[3][2] = {};
int min = 101, max = -1;
int countingArr[101] = {};
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 2; j++)
{
cin >> arr[i][j];
if (arr[i][j] > max)
max = arr[i][j];
if (arr[i][j] < min)
min = arr[i][j];
}
}
// 카운팅 배열 만들기
// 배열의 i번째 요소의 0번 = 도착 시간
// 배열의 i번째 요소의 1번 = 떠난 시간
for (int i = 0; i < 3; i++)
{
for (int j = arr[i][0]; j < arr[i][1]; j++)
{
countingArr[j]++;
}
}
// 각 시간마다 몇 대 머물렀는지 확인하고 그 시간에 따른 비용 합산
for (int i = min; i <= max; i++)
{
switch (countingArr[i])
{
case 1:
sum += A;
break;
case 2:
sum += B * 2;
break;
case 3:
sum += C * 3;
break;
}
}
cout << sum << endl;
}
- 잘 작동했고, 라인 수도 훨씬 줄어들었고 코드 자체도 간결해진 느낌이 있다.
- 메모리는 동일했지만 코드 길이에서 차이가 난다.
'자료구조와 알고리즘 > [Inflearn_큰돌] 10주 완성 C++ 코딩테스트' 카테고리의 다른 글
1주차-3. 1159번 농구 경기 (1) | 2022.09.26 |
---|---|
1주차-2. 10988번 팰린드롬인지 확인하기 (2) | 2022.09.13 |
1주차-0. 기초 개념 : 개념 강의 (0) | 2022.09.04 |
0주차-3. 기초 개념 : 조합(Combination) (0) | 2022.09.03 |
0주차-2. 기초 개념 : 순열(Permutation) (0) | 2022.09.03 |
댓글