프로그래머스 lv 2. 42583 c++ 다리를 지나는 트럭 **다시 풀어보기**

https://school.programmers.co.kr/learn/courses/30/lessons/42583

 

#include <bits/stdc++.h>

using namespace std;

int solution(int bridge_length, int weight, vector<int> truck_weights) {

	queue<int> wait; //통행하기를 기다리고 있는 차량들
	queue<int> bridge; // 다리위 차량들의 이동 상태. 빈 공간도 포함
    
    for( auto t: truck_weights) wait.push_back(t);
	int total = 0;
	int sec = 0;

	do {
		sec++;

		if (bridge.size() == bridge_length) { //다리 위에 차량이던지, 혹은 0 으로 꽉 차 있는 상태. 즉 맨 앞의 원소가 이제 다리에서 내릴 예정
			total -= bridge.front();
			bridge.pop();
		}

		if (!wait.empty() && (total + wait.front()) <= weight) { //기다리는 차량이 비어있지 않고, 다리위에 있는 총 차량들의 무게와 기다리고 있는 첫번째 차량의 무게를 합친것이 다리의 총 하중보다 작거나 같을때
			total += wait.front();//다리위에 올라갔기 때문에 total 무게에 추가
			bridge.push(wait.front());// 다리 위에 올라갔기 때문에 bridge에 추가
			wait.pop();
		} 
		else bridge.push(0); // 다리 위의 상태에 0 이라는 원소로 공간을 채움. 이 경우 그 위치에 건너는 것이 없는 상태

	} while (total); //total이 0이 될때까지 위의 과정을 지속적으로 수행. total이 0이 되었다는 의미는 모든 차량의 통행이 끝났다는 의미. 

	return sec;
}

bridge.push(0); 을 해주는것을 통해서, bridge.size()==bridge_length 비교시에 bridge.size()의 값을 사용해서 다리에서 가장 선두에 서있는 차량이 다리에서 내릴 위치가 되었을때를 판단한다. 

 

 

+++++++++

다른 사람의 풀이를 통해서 , 아래와 같은 코드를 보게 되었는데, 이때에 vector 컨테이너에 대해서 .at(count) 라는 형태로 접근하는 것을 보았다. 이에 대해서 궁금해서 이와 관련된 내용을 검색해보았고, 아래에 내용을 첨부하였다 

#include <iostream>
#include<algorithm>
#include <functional>         // greater 사용 위해 필요  
#include <vector>
#include<queue>
using namespace std;

int solution(int bridge_length, int weight, vector<int> truck_weights) {
    int answer = 0;
    int count = 0;
    int Time = 0; 
    int Truck_weight = 0;
    queue<pair<int, int>> truck_move;

    while (true)
    {
        if (weight >= Truck_weight + truck_weights.at(count))
        {
            truck_move.push(make_pair(truck_weights.at(count), bridge_length + 1 + Time));
            Truck_weight += truck_weights.at(count);
            count++;
        }

        if (count >= truck_weights.size())
        {
            answer = truck_move.back().second;
            break;
        }
        else
        {
            Time++;
            if (truck_move.front().second == Time+1)
            {
                Truck_weight -= truck_move.front().first;
                truck_move.pop();
            }
        }

    }

    return answer;
}
C++에서 `.at()`은 벡터(Vector)나 다른 시퀀스 컨테이너에서 특정 인덱스에 해당하는 요소를 접근하기 위한 멤버 함수입니다. 이 함수를 사용하여 벡터의 특정 위치에 있는 요소를 읽거나 수정할 수 있습니다.

`.at()` 함수는 다음과 같이 사용됩니다:

```cpp
value_type at (size_type n);
```

여기서:
- `value_type`: 컨테이너에 저장된 요소의 데이터 형식입니다.
- `size_type`: 인덱스를 나타내는 데이터 형식으로, 보통 `size_t` 형식을 사용합니다.
- `n`: 접근하려는 요소의 인덱스입니다.

`.at()` 함수는 주어진 인덱스가 유효한 범위 내에 있는지 확인하고, 유효하지 않은 경우 `std::out_of_range` 예외를 발생시킵니다. 이는 프로그램에서 범위를 벗어난 인덱스로 인한 오류를 방지하기 위한 안전장치입니다.

따라서 `.at()` 함수를 사용하면 배열 범위를 초과하는 인덱스로 인한 문제를 방지하고 안정성을 확보할 수 있습니다. 이 함수는 일반적으로 배열 요소에 접근하는 대괄호(`[]`) 연산자와 비교됩니다. `.at()`은 인덱스 범위 검사를 수행하므로 오류를 방지하려는 경우 유용합니다.

예를 들어, `truck_weights.at(count)`는 `truck_weights` 벡터에서 `count` 인덱스에 해당하는 요소를 반환합니다.

이에 대한 설명을 보면, vector의 원소들에 대한 접근을 할때, 나의 경우는 그동안 배열의 원소들에 접근하듯이 [ ] 을 이용한 접근을 하였는데, 이때에 out of bound 등 범위 밖으로 접근하는 경우 잘못된 접근을 통해서 문제가 발생할텐데, 이때에 그와 관련된 것들을 확인해주고, 만약 문제가 되는 접근이 있을시에 'std::out_of_range' 예외를 발생시켜 주는 것이 가능한 형태의 접근인듯 하다. 

백준에서 c++로 문제를 풀때는 배열(array)로 문제를 해결하다보니 vector를 사용하는 멤버함수들에 대해서는 잘 몰랐는데, 위와 같은것이 있다는 것을 알아두고, 만약 다른 사람의 코드에서 보게 된다면 .at() 이 원소에 접근하는 것이라는것을 기억하도록 하자. 

나도 다음에 원소에 접근할때 이런식으로 사용하는것도 좋을것 같다. 

 

아직까지도 백준에서 문제를 풀때 대부분 array를 통해서 해결해서, 이렇게 vector로 주어지는 자료에 대해서 완전하게 자유자재로 다루는 느낌이 없다. 그래도 익숙해지고 자유롭게 다룰 수 있을때까지 계속해서 노력해서 작성해보고 가지고 놀고 연습해보자. 

될때까지 해보자. 

 

  Comments,     Trackbacks