코딩 테스트

[코딩테스트 21일차] BAEKJOON 1712번, BAEKJOON 10811번, BAEKJOON 2587번

sunlight-dby 2025. 5. 23. 23:05

[BAEKJOON 1712번 : 손익분기점]

[문제]


[고찰]

처음에 해당 문제를 풀 때, 'C x (판매 수량) > A + B x (판매 수량)'을 만족하는 손익분기점을 1부터 시작하여 1씩 더하면서 찾으려고 했습니다.

 

하지만 너무 비효율적이기도 하고, 시간 제한을 생각해봤을 때 해당 방법은 아닌 것 같아 좀 더 고민을 해보았습니다.

 

그렇게 고민을 하다보니, 노트북 1대의 판매 비용 C가 가변 비용 B보다 작다면, 손익분기점을 넘을래야 넘을 수 없는 것을 깨달았고, 손익분기점은 고정 비용 A를 판매 비용 C와 가변 비용 B의 차로 나눈 뒤, 최소 정수를 보장하기 위해 1을 더해주면 찾을 수 있었습니다.


[개념]

손익분기점을 point라 하고, A, B, C를 문제에서 나오는 그대로 사용할 때,

C x point > A + B x point를 만족해야 합니다.

 

이를 정리하면,

(C - B) x point > A이고,   point > A / (C - B)입니다.

 

이때 point는 최소 정수를 보장해야 하기 때문에,

point = A / (C - B) + 1이 됩니다.


[정리]

문제에 제공되는 공식에 매몰되지 말고, 그 공식을 활용하여 더욱 전체적인 흐름을 보는 것이 중요한 것 같습니다.


[Solution]

#include <iostream>

using namespace std;

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);

	int A, B, C;
	cin >> A >> B >> C;

	int point = -1;

	if (B < C)
	{
		point = A / (C - B) + 1;
	}

	cout << point;

	return 0;
}

[BAEKJOON 10811번 : 바구니 뒤집기]

[문제]


[고찰]

해당 문제는 <algorithm>의 reverse를 사용하여 벡터의 원하는 구간을 역순으로 바꾸기만 하면 되는 간단한 문제입니다.

 

reverse는 iterator 또는 포인터를 인자로 받아서 사용되기 때문에, 저는 포인터를 사용하여 아래와 같이 reverse를 사용하였습니다.

reverse(&basket[before] - 1, &basket[after]);

 

 

이 방법 외에도 iterator를 사용한다면, 벡터의 begin() iterator에 before과 after을 더하여서 원하는 iterator에 접근할 수도 있습니다.

reverse(basket.begin() + before - 1, basket.begin() + after);

 

그러다 문득 reverse를 사용하지 않고는 어떻게 풀지 고민하다가 이를 정리하게 되었습니다.


[개념]

reverse 함수를 사용하지 않고 벡터(또는 배열)의 일부 구간을 뒤집는 로직은, 두 포인터를 이용해서 양 끝에서 서로 값을 바꿔주는 방식을 사용하면 됩니다.

 

예를 들어, basket[1]부터 basket[4]까지를 역순으로 뒤집고 싶을 때는

basket[1]과 basket[2]를 바꾸고, basket[2]와 basket[3]을 바꾸는 식으로 가운데로 오면서 교환을 반복합니다.

 

가운데로 오는 로직은 1의 값을 갖는 before을 1씩 더하고, 4의 값을 갖는  after를 1씩 빼주면 됩니다.

 

이를 코드로 구현하면 아래와 같습니다.

before -= 1;
after -= 1;

while (before < after)
{
    int temp = basket[before];
    basket[before] = basket[after];
    basket[after] = temp;
    
    before++;
    after--;
}

[정리]

함수를 활용하는 것도 중요하지만, 그 함수가 어떠한 원리로 사용되는지도 알아두는 것 역시 중요한 것 같습니다.


[Solution]

#include <iostream>
#include <vector>    
#include <algorithm> 

using namespace std;

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);

	int N, M;
	cin >> N >> M;

	vector<int> basket;
	int i = 1;

	while (N--)
	{
		basket.push_back(i);
		i++;
	}

	while (M--)
	{
		int before, after;
		cin >> before >> after;

		reverse(&basket[before] - 1, &basket[after]);
		// reverse(basket.begin() + before - 1, basket.begin() + after);와 동일
	}

	for (int i = 0; i < basket.size(); i++)
	{
		cout << basket[i] << " ";
	}

	return 0;
}

[BAEKJOON 2587번 : 대표값2]

[문제]


[고찰]

해당 문제는 애초에 입력 개수가 주어져있어, sort를 활용해 벡터(또는 배열)을 정렬만 할 수 있으면 되는 아주 쉬운 문제입니다.

 

다만, 이번에도 sort 함수를 사용하지 않고서는 어떻게 풀 수 있을지를 생각하다 정리하게 되었습니다.


[개념]

sort 함수를 사용하지 않고 푼다면, 선택 정렬(Selection Sort)를 활용하여 현재 이치에서 가장 작은 값을 찾아 교환하면 됩니다.

 

이를 코드로 구현하면 다음과 같습니다.

for (int i = 0; i < 4; i++)
{
    int minIndex = i;
    for (int j = i + 1; j < 5; j++)
    {
        if (num[j] < num[minIndex])
        {
            minIndex = j;
        }
    }
    
    int temp = num[i];
    num[i] = num[minIndex];
    num[minIndex] = temp;
}

[정리]

앞으로는 함수가 어떻게 동작하는지를 알아두는 것에도 초점을 맞춰가며 공부를 해나가야겠습니다.


[Solution]

#include <iostream>
#include <vector>    
#include <algorithm> 

using namespace std;

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);

	vector<int> num(5);
	int sum = 0;

	for (int i = 0; i < 5; i++)
	{
		cin >> num[i];
		sum += num[i];
	}

	sort(num.begin(), num.end());

	cout << sum / 5 << "\n" << num[2];

	return 0;
}