백준 13335 c++

magicdrill·2024년 5월 18일

백준 문제풀이

목록 보기
349/673

백준 13335 c++

쉬운 난이도의 큐를 사용하는 문제인데... 어디서부턴가 꼬여서 나도 못알아 볼 정도로 코드가 더럽고 복잡해졌다.... 예상과는 달리 실행시간은 오히려 짧은 편이지만 코드 가독성도 떨어지고 원래 챙기려했던 모듈성도 못챙겼다. 다른 문제로 다시 연습해 보겠다.

#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, &current_trucks_weight_on_bridge, &current_trucks_on_bridge, bridge.front());
		if(bridge_pass)//다리가 다음 트럭을 견딜 수 있으면?
			//견딜수 있는 조건 : 다리 하중이 현재 다리 위에 있는 모든 트럭 무게의 합보다 클 경우 and 다리 위에 다음 트럭을 위한 공간이 존재함
		{
			//견딜 수 있다면, 트럭 한대 넣기
			truck_pass(bridge_pass, next_truck, bridge, &current_trucks_weight_on_bridge, &current_trucks_on_bridge, &arrived_truck);
			if (!truck.empty())
			{
				truck.pop();
			}
		}
		else//다음 트럭을 견딜 수 없으면?
		{
			//현재 있는 트럭 하나씩 밀어내기
			truck_pass(bridge_pass, next_truck, bridge, &current_trucks_weight_on_bridge, &current_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;
}

0개의 댓글