쉬운 난이도의 큐를 사용하는 문제인데... 어디서부턴가 꼬여서 나도 못알아 볼 정도로 코드가 더럽고 복잡해졌다.... 예상과는 달리 실행시간은 오히려 짧은 편이지만 코드 가독성도 떨어지고 원래 챙기려했던 모듈성도 못챙겼다. 다른 문제로 다시 연습해 보겠다.
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
void input_truck(int *w, int *L, queue<int> &truck)
{
int n;
int i, truck_weight;
cin >> n >> *w >> *L;
for (i = 0; i < n; i++)
{
cin >> truck_weight;
truck.push(truck_weight);
}
return;
}
bool bridge_can_afford(int w, int L, int next_truck, int *current_trucks_weight_on_bridge, int *current_trucks_on_bridge, int passing_truck)
{
int next_trucks_weight_on_bridge = *current_trucks_weight_on_bridge + next_truck - passing_truck;//이번 통과로 다리위에 있던 트럭이 한대 빠지는걸 포함 한다면
int next_trucks_on_bridge = *current_trucks_on_bridge + 1;
if (passing_truck != 0)
{
next_trucks_on_bridge -= 1;
}
//매번 트럭의 총 무게, 총 대수를 구하면 모듈화는 좋겠지만...반복계산이 너무 많아지지 않나?// 매개 변수로 받기
if (next_trucks_weight_on_bridge <= L && next_trucks_on_bridge <= w)
{
*current_trucks_weight_on_bridge = *current_trucks_weight_on_bridge + next_truck;//이걸 여기서 저장할 필요가 있나?
*current_trucks_on_bridge = next_trucks_on_bridge;
return true;
}
else
{
return false;
}
}
void truck_pass(bool pass, int truck, vector<int> &bridge, int *current_trucks_weight_on_bridge, int *current_trucks_on_bridge, int *arrived_truck)
{
int i;
if (bridge.front() != 0)//이번 결과로 트럭이 다리를 통과하면?
{
*current_trucks_weight_on_bridge -= bridge.front();
*current_trucks_on_bridge -= 1;
*arrived_truck += 1;
}
//근데 이렇게 반복횟수를 늘리면 시간이 너무 낭비되는거 아닌가
if (pass)//다음 트럭이 지나갈 수 있으면?
{
for (i = 0; i < bridge.size() - 1; i++)
{
bridge[i] = bridge[i + 1];
}
bridge.back() = truck;
}
else//다음 트럭이 지나갈 수 없으면?
{
for (i = 0; i < bridge.size() - 1; i++)
{
bridge[i] = bridge[i + 1];
}
bridge.back() = 0;
}
/*
for (i = 0; i < bridge.size(); i++)
{
cout << bridge[i] << " ";
}
cout << "\n";
*/
return;
}
void find_answer(int *w, int *L, queue<int> &truck)
{
int full_time_count = 0;
int current_trucks_weight_on_bridge = 0;
int current_trucks_on_bridge = 0;
vector<int> bridge(*w, 0);
bool bridge_pass;
int arrived_truck = 0;
int trucks = truck.size();
int next_truck;
while (arrived_truck != trucks)//이렇게 하니까 다리에 다 올라간거만으로도 종료됨.... 도착한 트럭대수를 저장하는 변수 필요?
{
if (truck.empty())
{
next_truck = 0;
}
else
{
next_truck = truck.front();
}
bridge_pass = bridge_can_afford(*w, *L, next_truck, ¤t_trucks_weight_on_bridge, ¤t_trucks_on_bridge, bridge.front());
if(bridge_pass)//다리가 다음 트럭을 견딜 수 있으면?
//견딜수 있는 조건 : 다리 하중이 현재 다리 위에 있는 모든 트럭 무게의 합보다 클 경우 and 다리 위에 다음 트럭을 위한 공간이 존재함
{
//견딜 수 있다면, 트럭 한대 넣기
truck_pass(bridge_pass, next_truck, bridge, ¤t_trucks_weight_on_bridge, ¤t_trucks_on_bridge, &arrived_truck);
if (!truck.empty())
{
truck.pop();
}
}
else//다음 트럭을 견딜 수 없으면?
{
//현재 있는 트럭 하나씩 밀어내기
truck_pass(bridge_pass, next_truck, bridge, ¤t_trucks_weight_on_bridge, ¤t_trucks_on_bridge, &arrived_truck);
}
full_time_count++;
}
cout << full_time_count << "\n";
return;
}
int main(void)
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int w, L;
queue <int> truck;
input_truck(&w, &L, truck);
find_answer(&w, &L, truck);
return 0;
}