Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- 중위 표기법
- 서로소 집합
- 다이나믹 프로그래밍
- 탐욕 알고리즘
- deque
- 이진탐색트리
- binary search
- divide and conquer
- 3190번
- BST
- 알고리즘 문제
- 이진 검색
- disjoint-sets
- 최소 비용 신장 트리
- 알고리즘
- 최단 경로 알고리즘
- 트리
- quick-sort
- 프로세스의 상태
- merge-sort
- 부분 집합
- 자료구조
- CPU scheduling
- 프로세스
- 후위 표기법
- 동적 계획법
- kruskal 알고리즘
- prim 알고리즘
- 완전 탐색
- union-find
Archives
- Today
- Total
Dionysus
[알고리즘 문제 풀이🙄] 백준 13335. 트럭 (silver 1) 본문
📌 문제 요약
강 위의 다리를 n개의 트럭이 지나가려고 한다. 다리 위에는 w대의 트럭만이 동시에 올라갈 수 있다고 할 때, 모든 트럭들이 다리를 건너는 최단 시간을 출력하라. (단, 트럭의 순서는 변경할 수 없으며 트럭의 무게는 서로 같지 않을 수 있다. 또한 트럭들은 하나의 단위 시간에 하나의 단위 길이만큼만 이동할 수 있다고 가정한다.)
😖 내가 생각한 로직 + 알고리즘
현재 다리 위에 있는 트럭의 무게를 group 변수에 저장하고, 현재 다리 위에 있는 트럭들의 첫 번째 트럭 순서 정보를 startTruck 변수에 저장한다. 또한 다리 위에 올라가지 못한 트럭들 중 가장 순서가 빠른 트럭의 순서 정보를 nextTruck 변수에 저장한다. 그리고 nextTruck 변수의 값이 n과 같거나 작은 동안 아래의 과정을 반복한다.
- nextTruck의 무게를 group에 더했을 때, 제한 하중(L)을 초과하지 않는다면 포함시킨다.
- nextTruck += 1, needTime += 1
- nextTruck 무게가 group에 더해졌다는 것은 다리 위에 올라갔음을 의미하는 것이므로 시간이 1초 흐른 것으로 초기화한다.
- nextTruck += 1, needTime += 1
- 만약 제한하중을 초과한다면 현재 형성된 group으로 다리를 건너야 하는 것이므로 startTruck이 다리를 완전히 건넌 것으로 되는 시점으로 needTime 변수 정보를 수정하고, group에서 startTruck의 무게를 제외시킨다.
- 그리고 startTruck += 1
# n: 트럭의 수, w: 다리 길이, L: 다리의 최대 하중
n, w, L = map(int, input().split())
weights = [0]
weights += [i for i in map(int, input().split())]
startTruck = 1
nextTruck = 2
group = weights[startTruck]
needTime = 1
while nextTruck <= n:
if group + weights[nextTruck] <= L and nextTruck - startTruck <= w:
group += weights[nextTruck]
nextTruck += 1
needTime += 1
else:
needTime += w - (nextTruck - startTruck) + 1
group -= weights[startTruck]
startTruck += 1
if group + weights[nextTruck] <= L:
group += weights[nextTruck]
nextTruck += 1
if needTime < w:
needTime += w - (nextTruck - startTruck)
print(needTime + (n - startTruck + 1))
▶ 내 코드가 틀린 이유를 모르겠다.
🧐 참고한 코드
# n: 트럭의 수, w: 다리 길이, L: 다리의 최대 하중
n, w, L = map(int, input().split())
cars = list(map(int, input().split()))
# 큐를 이용해서 구현
# 처음에 다리의 길이만큼 0을 넣어준다 -> 차가 다리에 들어와서 나가는 거 시간 카운트할 수 있도록 빈 공간을 넣어준다.
q = deque()
for _ in range(w):
q.append(0)
time = 0
idx = 0
while idx < n:
time += 1
q.popleft()
# 지금 차 들어가도 다리 하중이 넘지 않는 경우
if sum(q) + cars[idx] <= L:
q.append(cars[idx])
idx += 1
# 넘으면 이전 차만 앞으로 가는 거고 빈공간이 생기는 거니까 0 넣어줌
else:
q.append(0)
# 다리에 차가 다 나가야 하므로 큐가 빌때까지
while q:
time += 1
q.popleft()
print(time)
📌 Python의 deque[데크] (from collections)
deque는 앞, 뒤에서 데이터를 처리할 수 있는 양방향 자료형으로 stack처럼 사용해도 되고 queue처럼 사용해도 된다. list와 매우 비슷하지만, appendLeft(x)와 popleft(x)와 같이 모듈에 내장된 함수가 존재하여 list에 비해 속도가 매우 빠르다.
▷ 예를 들어 list에서 첫 번째 요소 삭제를 위해 pop(0)을 사용하는 경우 시간복잡도는 O(N)이지만, deque에서는 popleft()를 사용하여 시간복잡도가 O(1)에 불과하다.
▶ 따라서 스레드 환경에서 안전하다는 장점을 가진다.
🤗 제출 후 pass한 코드
from collections import deque
# n: 트럭의 수, w: 다리 길이, L: 다리의 최대 하중
n, w, L = map(int, input().split())
weights = list(map(int, input().split()))
passed = []
q = deque()
q.append(weights[0])
weight_sum = weights[0]
i = 1
while i < n:
# 다리 위가 꽉 찼을 때
if len(q) >= w:
passed.append(q.popleft())
weight_sum -= passed[-1]
continue
if weight_sum + weights[i] <= L:
q.append(weights[i])
weight_sum += weights[i]
i += 1
else:
q.append(0)
for _ in range(len(q)):
passed.append(q.popleft())
for _ in range(w):
passed.append(0)
print(len(passed))
😎 앞으로의 개선 방향
이번 문제를 풀면서, 문제 풀이에 알맞는 자료구조에 대한 지식이 부족하다는 생각이 들었다. 또한 문제를 풀고나서도 내 코드가 참고한 코드보다 지저분한 것을 보니 코드를 좀더 가독성 좋게 짜는 연습도 많이 해야겠다는 생각이 들었다.😔
'CS 및 알고리즘 공부 > 알고리즘 문제 풀이' 카테고리의 다른 글
[알고리즘 문제 풀이🙄] 백준 3190. 뱀 (gold 4) (1) | 2024.10.02 |
---|---|
[알고리즘 문제 풀이🙄] 20551. 증가하는 사탕 수열 (0) | 2024.09.09 |
[알고리즘 문제 풀이🙄] 5656. 벽돌 깨기 (0) | 2024.09.09 |
[알고리즘 문제 풀이🙄] 1486. 장훈이의 높은 선반 (1) | 2024.09.06 |
[알고리즘 문제 풀이🙄] 1861. 정사각형 방 (0) | 2024.09.06 |