문제
https://programmers.co.kr/learn/courses/30/lessons/42583
트럭 여러 대가 강을 가로지르는 일 차선 다리를 정해진 순으로 건너려 합니다. 모든 트럭이 다리를 건너려면 최소 몇 초가 걸리는지 알아내야 합니다. 트럭은 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 |
알고리즘
def solution(bridge_length, weight, truck_weights):
# 시점
time = 0
# 다리를 지나고 있는 트럭
passing = []
# 다리를 다 건넌 트럭
passed = []
# 대기하고 있는 트럭이 없을 때까지 반복한다.
while truck_weights:
# 시점을 1 더한다.
time += 1
print("\n-----현재 시점은", time, "입니다-------")
# 한번 반복하는 동안(한 시점에서 다음 시점으로 가는 동안), 다리를 건너고 있는 버스가 도착하는 것을 구현했다.
# 다리를 건너고 있는 버스가 있다면,
if passing:
for i in range(len(passing)):
# passing[i][1]의 값을 1 빼준다. passing[i][1]의 값은, 버스가 다리를 건너기 시작한 시점부터 부여받은 bridge_lenth이다
# 즉, 다리를 건너기까지 남은 시간이 매 시점이 지날때마다 1씩 감소하는 것이다.
passing[i][1] -= 1
print("무게 " + str(passing[i][0]) + "인 버스 가는중, 버스 정보: " , "버스 무게: ", passing[i][0], "남은 시간: ", passing[i][1])
# 그렇게 1초가 지나고, 버스가 도착하기 까지 남은 시간이 0이라면 그 버스는 도착한 것이다.
# passing배열을 순회하면서,
if passing:
print('남은 시간: ', passing[0][1])
# 가장 먼저 passing배열에 추가된 원소의 첫번째 값이 0이라면 그 원소를 pop해서, passed배열의 원소로 append한다.
if passing[0][1] == 0:
print("버스가 도착했습니다")
print("도착한 버스 무게: ", passing[0][0])
passed.append(passing.pop(0))
print("도착한 버스들 목록: ", passed)
# 버스 출발
print("\n대기중인 버스 출발여부 판단하겠습니다")
print("대기중인 버스 무게: ", truck_weights[0])
# 현재 다리의 무게를 구하기 위한 변수 current_weight
current_weight = 0
for i in range(len(passing)):
current_weight += passing[i][0]
print("currnet_weight: ", current_weight)
# 현재 다리를 지나고 있는 버스의 무게와, 대기중인 첫 번째 버스의 무게를 더한 값을 다리가 지탱할 수 있는 무게와 비교한다
# 만약 두 값을 더한 값이 다리의 최대 무게보다 작다면
if current_weight + truck_weights[0] <= weight:
# 대기중인 배열의 원소를 하나 빼고, 건너는 시간을 나타내는 bridge_length값을 포함한 배열 형태를 passing에 append한다.
passing.append([truck_weights.pop(0), bridge_length])
print("무게", passing[0][0], "인 버스 출발합니다")
# 두 값을 더한 값이 다리의 최대 무게보다 작다면 대기중인 버스는 출발하지 못한다.
else:
print("무게 초과로 버스 출발 안함")
print("---------"+str(time)+"초 시점 종료-------------")
# 마지막 버스가 출발한 시점부터, 도착하기 까지 걸리는 시간인 bridge_length를 더해서 리턴한다
return time + bridge_length
bridge_length = 100
weight = 100
truck_weights = [10,10,10,10,10,10,10,10,10,10]
print("정답: ", solution(bridge_length, weight, truck_weights))
설명
이 문제를 풀면서 사용한 자료구조는 리스트이다. 큐를 잘 알았더라면 좋았겠지만, 리스트도 활용하기에 따라 큐처럼 쓸 수 있으므로 리스트를 사용하였다.
- passing[]: 현재 다리를 지나고 있는 트럭의 정보를 담은 배열이다. 각 원소들은 [트럭의 무게, 도착까지 남은 시간]형태이다.
- passed[]: 다리를 건넌 트럭들의 정보를 담은 배열이다.
- truck_weights[]: 문제에서 입력으로 주어지는 배열이다.
문제를 고민하다가, 한 시점마다 해야할 일을 정해주기로 했다. 위 코드에도 나와있듯이, 한 시점이 지날때마다 확인해야 하는 것은 다음과 같다.
- 다리 위를 지나고 있는 트럭이 도착하기까지 남은 시간을 1씩 뺀다.
- 남은 시간을 1 뺐는데, 그 남은 시간이 0이라면 그 트럭을 도착한 것으로 간주한다.
- 대기 중인 트럭이 출발할 수 있는지 판단하고, 기준에 부합한다면 출발해야 한다.
위의 제약 사항들을 아래와 같이 구현하였다.
- -> passing배열을 순회하면서 passing[i][1] 을 1 감소시키는 것으로 구현
- -> passing배열에서 0번째 원소를 pop하고, pop한 원소를 passed배열에 append하는 것으로 구현
- -> passing배열을 순회하면서 모든 무게를 더하고, 대기중인 트럭의 무게까지 더해서 weight보다 작으면 trucks_weight에서 pop한 후 passing배열에 [트럭의 무게, bridge_length]형태로 append, 아니면 대기하는 것으로 구현
결과
후기
내가 풀어본 문제중에 좀 복잡한 문제였다. 생각을 정리하느라 쓴 공책 종이가 네다섯장은 되는듯 하다. 아직 초보인지라 어떻게 접근해야 할 지를 감을 못잡아아서, 최대한 차근차근 구현했다. 처음에는 버스가 조건에 맞게 출발하는지, 배열들은 출발에 따른 동작을 올바르게 하는지 구현했다. 그 다음에는 버스가 가고있는 것을 구현했고, 그 다음에 버스가 도착하는 것을 구현했다. 이렇게 해야 할 일들을 말로 풀어서 크게크게 쪼개놓고, 그것을 더 쪼개서 해당하는 동작들을 정의한 다음에야 코드가 써졌다. 아주아주 좋은 경험이었다. 바로 이맛이야 캬하하하하~~~~
'공부 > 알고리즘' 카테고리의 다른 글
[프로그래머스 스택/큐]프린터 - Python3 (8) | 2020.01.16 |
---|---|
[프로그래머스 스택/큐]기능 개발 - Python3 (0) | 2020.01.13 |
[프로그래머스 스택/큐]탑 - Python3 (0) | 2020.01.13 |
[프로그래머스 해시]위장- Python3 (0) | 2020.01.13 |
[백준 2798/완전탐색] 블랙잭 - Python3 (2) | 2020.01.08 |