파이썬으로 프로그래머스 풀기 :: 다리를 지나는 트럭
문제 설명
트럭 여러 대가 강을 가로지르는 일 차선 다리를 정해진 순으로 건너려 합니다. 모든 트럭이 다리를 건너려면 최소 몇 초가 걸리는지 알아내야 합니다. 트럭은 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 |
문제 링크 : https://programmers.co.kr/learn/courses/30/lessons/42583
코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | def solution(bridge_length, weight, truck_weights) : truck_weights = truck_weights[::-1] n = len(truck_weights) passing_weight = [0]*n passed = []; passing = [] i = 0; j = -1 while len(passed)<n : if len(truck_weights)>0 and sum(passing) + truck_weights[-1] <= weight : passing.append(truck_weights.pop()) j+=1 passing_weight[:j+1] = [passing_weight[z]+1 for z in range(j+1)] if passing_weight[i] == bridge_length : passed.append(passing[0]) passing = passing[1:] i+=1 return passing_weight[0]+1 | cs |
* truck_weights[::-1] 이유는 효율성때문이다. truck_weights를 거꾸로 뒤집어주지 않으면 truck_weights.pop()이 아닌 truck_weights.pop(0)을 해야하는데, 이렇게 되면 첫 번째 원소를 빼고 그 뒤에 원소들을 한칸씩 앞으로 모두 땡겨줘야하기 때문에 O(n)만큼 걸린다. 즉 비효율적이다.
따라서 truck_weights를 거꾸로 뒤집어 truck_weights.pop() 으로 해주면 가장 뒤에 원소만 하나씩 빠지기 때문에 O(1)에 할 수 있다.
변수설명
passing_weight : 각 트럭이 다리에 오르는 순간부터 얼마의 시간이 흘렀는지를 나타내는 리스트
passed : 지나간 트럭
passing : 지나는 중인 트럭
i : 가장 선두에서 지나는 트럭의 index :: bridge_length만큼 다리위에 있었는지 확인하기 위함
j : 가장 최근 다리에 올라간 트럭의 index :: passing_weight에 indexing하기 위함
다음과 같은 상태에서 시작한다.
가장 먼저 첫 번째 대기중인 트럭이 다리위에 올라간다.(j+=1)
따라서 첫 번째 트럭이 다리에 오르고 1초가 흘렀음을 passing_weight에 표시한다.
2초가 흘러 첫 번째 트럭이 다리를 지나갔다.(i+=1)
이 때, 지나가는 중인 트럭(7)과 대기중인 트럭(4)의 합이 weight보다 크기 때문에 두 번째 트럭은 아직 올라가지 못한다.
두 번째 트럭이 다리위에 올라갔다.(j+=1)
2초가 지나면서 두 번째 트럭은 다리를 빠져나오고(i+=1), 세 번째 트럭이 올라간다.(j+=1)
이를 계속 반복한다.
총 걸린시간은 첫 번째 트럭이 다리에 올라간 시간부터 마지막 트럭이 빠져나간 시간까지이며, 이는 passing_weight 첫 번째 값에 +1 한 값이다. (+1은 마지막 트럭이 빠져나오는 시간을 더해 준 것)
'코딩테스트 연습 > 프로그래머스' 카테고리의 다른 글
[프로그래머스] 베스트앨범 in python (0) | 2019.12.13 |
---|---|
[프로그래머스] 숫자 야구 in python (0) | 2019.12.12 |
[프로그래머스] 쇠막대기 in python (0) | 2019.12.10 |
[프로그래머스] 가장 큰 수 in python (2) | 2019.12.09 |
[프로그래머스] 카펫 in python (5) | 2019.12.08 |