티스토리 뷰
https://school.programmers.co.kr/learn/courses/30/lessons/42583
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
이 문제는 다리의 길이, 다리가 견딜 수 있는 무게, 트럭 별 무게가 주어질 때, 모든 트럭이 다리를 건너기 위해 필요한 최소 시간을 구하는 문제이다. 이 문제를 풀기 위한 흐름은 문제 설명을 보면 이해하기 쉽다. 문제 설명에도 나와있듯, 각 시간마다 트럭이 다리를 벗어날 수 있는지, 트럭이 다리에 올라갈 수 있는지만 검사하면 된다. 만약 현재 시간에서 다리 제일 앞에 있는 트럭이 다리를 벗어날 수 있다면, 그 트럭을 다리 위에서 제거하면 된다. 그 후, 현재 대기 중인 트럭이 다리 위에 올라갈 수 있으면 다르에 현재 트럭을 올린다.
이를 구현하기 위해 고민해야할 것이 두 가지가 있다. 우선, 먼저 다리에 올라간 트럭이 먼저 다리를 나가는 것을 어떻게 구현하냐는 것이다. 이는 큐(Queue)를 이용해 구현할 수 있다. 큐는 간단히 말해 먼저 들어간 것이 먼저 나오는 구조로, 먼저 줄을 선 사람이 먼저 들어가는(나가는) 것을 생각하면 된다. 문제의 상황도 이와 같기에 큐를 이용할 것이다. 그리고 트럭이 다리를 나갈 수 있는지 판별할 조건이다. 이는 트럭이 다리에 올라간 시간을 이용해 판별할 수 있다. 예를 들어, 문제 설명의 예시에서 무게가 4인 트럭은 시간이 3일 때 다리에 올라갔다가 시간이 5일 때 다리를 벗어났다. 이는 시간이 3일 때 다리에 올라가 다리 길이 2만큼의 시간이 지난 후에 다리를 벗어난 것이므로, 현재 시간 - 다리에 올라간 시간과 다리 길이를 비교하여 다리를 벗어날 수 있는지 아닌지를 판별할 수 있다. 이것들을 고려한 흐름은 다음과 같다.
- 반복문을 이용하여 2번부터의 과정을 실시한다.
- 만약 다리 위에 트럭이 존재한다면, 그 트럭이 다리를 나갈 수 있는지 검사한다.
- 만약 현재 시간에서 현재 다리의 가장 앞에 있는 트럭의 다리 위에 올라온 시간을 뺀 값이 다리 길이와 같거나 크다면, 그 트럭은 다리를 나갈 수 있다.
- 만약 트럭이 다리 위에 올라갈 수 있다면, 다리 위에 넣는다.
- 만약 다리 위의 트럭 수가 다리 길이보다 작고, 현재 다리 위의 총 트럭 무게 + 현재 트럭 무게가 주어진 무게 제한보다 작을 경우, 다리 위에 올라갈 수 있다.
#include <string>
#include <vector>
#include <queue>
using namespace std;
int solution(int bridge_length, int weight, vector<int> truck_weights) {
int answer = 0;
int truckIdx = 0; // 트럭의 인덱스
int current = 1; // 현재 시간 (경과 시간 1부터 트럭이 다리에 올라갈 수 있다.)
int totalWeight = 0; // 다리 위의 트럭들 무게의 합
queue<pair<int, int>> trucksOnBridge; // first: 무게, second: 다리에 올라온 시간
// 모든 트럭이 다리에 올라가지 못했거나, 다리 위에 트럭이 존재하는 경우 반복문을 진행한다.
while(truckIdx < truck_weights.size() || trucksOnBridge.size() > 0)
{
// 이미 다리를 건넌 트럭은 다리 위에서 제거한다.
while(trucksOnBridge.empty() == false)
{
pair<int, int> truck = trucksOnBridge.front();
// 현재 시간 - 트럭이 다리에 올라간 시간 >= 다리 길이 -> 다리를 건넘
if (current - truck.second >= bridge_length)
{
trucksOnBridge.pop();
totalWeight -= truck.first;
}
else
break;
}
// 만약 현재 트럭의 인덱스가 주어진 트럭의 범위 안이라면
// 트럭이 다리에 올라갈 수 있는지 검사한다.
if (truckIdx < truck_weights.size())
{
int currentTruck = truck_weights[truckIdx];
// 만약 다리에 트럭이 올라갈 공간이 있으면서
// 현재 다리 위의 트럭들의 총 무게 + 현재 트럭 무게 <= 주어진 무게 조건 이라면 다리로 올라갈 수 있다.
if (trucksOnBridge.size() < bridge_length && totalWeight + currentTruck <= weight)
{
trucksOnBridge.push({ currentTruck, current }); // 다리에 올라간 것을 표현
totalWeight += currentTruck; // 총 무게에 현재 트럭의 무게를 더해준다.
++truckIdx; // 다음 트럭을 가리킴
}
}
++current; // 시간이 1 경과한다.
}
answer = current - 1; // 마지막 차례에서 ++current; 한 거를 빼줘야 한다.
return answer;
}
'알고리즘 문제' 카테고리의 다른 글
프로그래머스 - 표 편집 (C++) (1) | 2023.06.16 |
---|---|
프로그래머스 - 자물쇠와 열쇠 (C++) (0) | 2023.06.14 |
프로그래머스 - 여행경로 (C++) (0) | 2023.06.01 |
프로그래머스 - 불량 사용자 (C++) (0) | 2023.05.31 |
프로그래머스 - 가장 먼 노드 (C++) (0) | 2023.05.09 |
- Total
- Today
- Yesterday
- Next.js
- 프로그래머스
- 타입스크립트
- SQL
- 비트마스킹
- 햄버거버튼
- 백준
- 자바스크립트
- Redux
- typescript
- aws
- 리액트
- 순열
- react
- 구현
- 스택
- themoviedb
- 완전탐색
- NextJS
- 다이나믹프로그래밍
- 알고리즘
- C++
- 카카오맵
- 코드스테이츠
- BFS
- CSS
- 브루트포스
- 넥스트js
- async
- 동적계획법
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |