문제 설명
트럭 여러 대가 강을 가로지르는 일 차선 다리를 정해진 순으로 건너려 합니다. 모든 트럭이 다리를 건너려면 최소 몇 초가 걸리는지 알아내야 합니다. 트럭은 1초에 1만큼 움직이며, 다리 길이는 bridge_length이고 다리는 무게 weight까지 견딥니다.
※ 트럭이 다리에 완전히 오르지 않은 경우, 이 트럭의 무게는 고려하지 않습니다.
예를 들어, 길이가 2이고 10kg 무게를 견디는 다리가 있습니다. 무게가 [7, 4, 5, 6]kg인 트럭이 순서대로 최단 시간 안에 다리를 건너려면 다음과 같이 건너야 합니다.
경과 시간 | 다리를 지난 트럭 | 다리를 건너는 트럭 | 대기 트럭 |
0 | [] | [] | [7,4,5,6] |
1~2 | [] | [7] | [4,5,6] |
3 | [7] | [4] | [5,6] |
4 | [7] | [4,5] | [6] |
5 | [7,4] | [5] | [6] |
6~7 | [7,4,5] | [6] | [] |
8 | [7,4,5,6] | [] | [] |
따라서, 모든 트럭이 다리를 지나려면 최소 8초가 걸립니다.
solution 함수의 매개변수로 다리 길이 bridge_length, 다리가 견딜 수 있는 무게 weight, 트럭별 무게 truck_weights가 주어집니다. 이때 모든 트럭이 다리를 건너려면 최소 몇 초가 걸리는지 return 하도록 solution 함수를 완성하세요.
제한 조건
- bridge_length는 1 이상 10,000 이하입니다.
- weight는 1 이상 10,000 이하입니다.
- truck_weights의 길이는 1 이상 10,000 이하입니다.
- 모든 트럭의 무게는 1 이상 weight 이하입니다.
입출력 예
bridge_length | weight | truck_weights | return |
2 | 10 | [7,4,5,6] | 8 |
100 | 100 | [10] | 101 |
100 | 100 | [10,10,10,10,10,10,10,10,10,10] | 110 |
stack을 사용한다면 truck_weights를 스택에 넣고
현재 다리의 weight를 b_weight라는 변수로 만들어 저장해 둡니다.
stack에서 트럭을 하나씩 빼는 것을 다리에 트럭이 진입한 것이라고 볼 수 있습니다.
트럭이 진입하고 1초 뒤에 다음 트럭이 진입할 수 있게 됩니다.
첫번째 트럭을 스택에서 빼내고 +1초를 해줍니다. 동시에 첫번쨰 트럭의 시간에서 -1을 해줍니다.
(만약 트럭의 시간이 0이되면 b_weight에서 해당 트럭의 무게를 뺍니다.)
그리고 다음 트럭의 weight를 보고 다리에 올라올 무게가 weight보다 크지 않으면 트럭을 하나 더 올립니다.
이렇게 트럭이 모두 없어질 때까지 반복하면 됩니다.
#include <string>
#include <vector>
#include <stack>
using namespace std;
int solution(int bridge_length, int weight, vector<int> truck_weights) {
int answer = 0;
int count = 0;
int i=0;
int tmp_weight = weight;
vector<int> t_time;
stack<int> s1;
for(int i=truck_weights.size()-1;i>=0;i--){
s1.push(truck_weights[i]);
t_time.push_back(bridge_length);
}
do{
if(!s1.empty() &&((tmp_weight - s1.top()) >= 0)){
tmp_weight -= s1.top();
s1.pop();
count++;
}
answer++;
for(int k=0;k<count;k++){
t_time[i+k]--;
}
if(t_time[i]==0){
tmp_weight += truck_weights[i];
i++;
count--;
}
}
while(count != 0 || i < truck_weights.size());
answer++;
return answer;
}
나의 점수는 1054(+6)점이었다.
또 다른 풀이 해석 :
#include <string>
#include <vector>
#include <queue>
using namespace std;
int solution(int bridge_length, int weight, vector<int> truck_weights) {
int answer = 0;
int tot_w = 0; //다리의 총 무게
int t_front = 0; //다리위에 있는 버스 중 가장 먼저 들어간 버스
int t_cur = 0; //다리위에 있는 버스 중 가장 마지막에 다리로 들어간 버스 id
int sec = 0; //소요된 시간
queue <int> q; //버스가 다리에 진입하는 시간을 담을 queue
while (t_front != truck_weights.size()) {//모든 트럭이 다 빠져나온 경우
if (!q.empty() && (sec - q.front() == bridge_length)) { //첫번째 버스가 다리를 빠져나오는가?
tot_w -= truck_weights[t_front]; //다리의 무게에서 빠져나오는 버스의 무게를 제외함
++t_front;
q.pop();
}
if (t_cur != truck_weights.size() && tot_w + truck_weights[t_cur] <= weight) {//다리에 아직 여유공간이 있을 경우
tot_w += truck_weights[t_cur];
++t_cur;
q.push(sec);
}
++sec;
}
answer = sec;
return answer;
}
반성 : 나는 다리 위에 있는 모든 버스의 시간을 고려했는데 그럴 필요가 없었다는 것을 깨닳았다.
마지막에 남은 버스가 빠져나오는 시간을 구하기만 하는 문제였다는 것을 문제를 다 푼 후에야 깨닳은 것이다.
앞으로 문제 유형을 많이 보다보면 이는 해결될 것이라고 생각한다.
앞으로도 열심히 코딩테스트 문제를 풀어봐야겠다.
'전공공부 > 코딩테스트' 카테고리의 다른 글
프로그래머스 스택/큐 기능개발 (2) | 2021.04.03 |
---|---|
프로그래머스 스택/큐 주식가격 (1) | 2021.03.31 |
프로그래머스 해시 베스트앨범 (0) | 2021.03.28 |
프로그래머스 위장 (0) | 2021.03.28 |
프로그래머스 전화번호 목록 (0) | 2021.03.28 |