백준 알고리즘 | 1712번 문제: 손익분기점
출처
https://www.acmicpc.net/problem/1712
문제
월드전자는 노트북을 제조하고 판매하는 회사이다. 노트북 판매 대수에 상관없이 매년 임대료, 재산세, 보험료, 급여 등 A만원의 고정 비용이 들며, 한 대의 노트북을 생산하는 데에는 재료비와 인건비 등 총 B만원의 가변 비용이 든다고 한다.
예를 들어 A=1,000, B=70이라고 하자. 이 경우 노트북을 한 대 생산하는 데는 총 1,070만원이 들며, 열 대 생산하는 데는 총 1,700만원이 든다.
노트북 가격이 C만원으로 책정되었다고 한다. 일반적으로 생산 대수를 늘려 가다 보면 어느 순간 총 수입(판매비용)이 총 비용(=고정비용+가변비용)보다 많아지게 된다. 최초로 총 수입이 총 비용보다 많아져 이익이 발생하는 지점을 손익분기점(BREAK-EVEN POINT)이라고 한다.
A, B, C가 주어졌을 때, 손익분기점을 구하는 프로그램을 작성하시오.
입력
첫째 줄에 A, B, C가 빈 칸을 사이에 두고 순서대로 주어진다. A, B, C는 21억 이하의 자연수이다.
출력
첫 번째 줄에 손익분기점 즉 최초로 이익이 발생하는 판매량을 출력한다. 손익분기점이 존재하지 않으면 -1을 출력한다.
1000 70 170
11
3 2 1
-1
2100000000 9 10
2100000001
노트
이 문제에서 설명하는 손익분기점은 회계학에서 정의하는 손익분기점과 다를 수 있다.
알고리즘 분류
- 수학
- 사칙연산
문제 풀이
손익분기점이 존재하는 경우
A(고정 비용)=1000, B(가변 비용)=70, C(1대 가격)=170, n(판매 대수)=?
판대 대수 | 총 비용 | 총 수입 | 비교 |
---|---|---|---|
수식 | A + (B * n) = 총 비용 | C * n = 총 수입 | |
1 | 1000 + 70 * 1 = 1070 | 170 * 1 = 170 | |
2 | 1000 + 70 * 2 = 1140 | 170 * 2 = 340 | |
3 | 1000 + 70 * 3 = 1210 | 170 * 3 = 510 | |
4 | 1000 + 70 * 4 = 1280 | 170 * 4 = 680 | |
5 | 1000 + 70 * 5 = 1350 | 170 * 5 = 850 | |
6 | 1000 + 70 * 6 = 1420 | 170 * 6 = 1020 | |
7 | 1000 + 70 * 7 = 1490 | 170 * 7 = 1190 | |
8 | 1000 + 70 * 8 = 1560 | 170 * 8 = 1360 | |
9 | 1000 + 70 * 9 = 1630 | 170 * 9 = 1530 | |
10 | 1000 + 70 * 10 = 1700 | 170 * 10 = 1700 | 비용 = 수입 |
11 | 1000 + 70 * 11 = 1770 | 170 * 11 = 1870 |
손익분기점이 존재하지 않는 경우
A(고정 비용)=3, B(가변 비용)=2, C(1대 가격)=1
판대 대수 | 총 비용 | 총 수입 |
---|---|---|
1 | 3 + 2 * 1 = 5 | 1 * 1 = 1 |
1 | 3 + 2 * 2 = 7 | 1 * 2 = 2 |
가변 비용(B)가 1대 가격(C)보다 작게 되면, 손기분기점이 존재하지 않는다.
B >= C | 2 >= 1
통과 하지 못한 코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
// 입력
StringTokenizer input = new StringTokenizer(br.readLine(), " ");
final long a = Long.parseLong(input.nextToken()); // 고정 비용
final long b = Long.parseLong(input.nextToken()); // 가변 비용
final long c = Long.parseLong(input.nextToken()); // 1대 가격
// 계산
if (b >= c) { // 가변 비용이 1대 가격보다 같거나 크면, 손기분기점이 없다. 3 2 1 인 경우, 2 >= 1
System.out.println(-1);
return;
}
int n = 0; // 판매 대수
long cost = 0; // 총 비용(=고정 비용+가변 비용)
long income = 0; // 총 수입(판매 비용)
do {
n++;
cost = a + (b * n);
income = c * n;
// 디버그용
//System.out.println("n=" + n + ", cost=" + cost + ", income=" + income);
} while (cost >= income);
// 출력
System.out.println(n);
}
}
}
수식대로 차례대로 계산하니 결과를 맞는데, 오래걸려서 “시간 초과"로 실패하였다.
그렇다면, 수식대로 계산을 계속 할게 아니라, 계산 공식을 만들어야 할 거 같다. 위에 테이블을 자세히 보면, 총 비용과 총 수입이 같아지는 순간 이후에 손익분기점이 된다는 것을 알 수 있다.
이를 수식으로 표현하여 공식을 구하면 아래와 같다.
고정 비용 + (가변 비용 * 판매 대수) = 1대 가격 * 판매 대수 = 손익분기점 직전
A + (B * n) = C * n
A = C * n - B * n
A = (C - B) * n
A / (C - B) = n -> 계산 공식!!
계산 공식에 예제 수를 대입 시켜 보면 아래와 같다.
A(고정 비용)=1000, B(가변 비용)=70, C(1대 가격)=170
A / (C - B) = n
1000 / (170 - 70) = 10
총 비용과 총 수입이 같아지는 순간. 즉, 손익분기점 직전은 10대를 팔았을 경우이다. 여기에 1을 더하면 11대를 팔았을 손익분기점을 넘기게 된다.
A / (C - B) + 1 = n -> 최종 계산 공식!!
이를 바탕으로 프로그램을 만들어 보자.
통과한 코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
// 입력
StringTokenizer input = new StringTokenizer(br.readLine(), " ");
final long a = Long.parseLong(input.nextToken()); // 고정 비용
final long b = Long.parseLong(input.nextToken()); // 가변 비용
final long c = Long.parseLong(input.nextToken()); // 1대 가격
// 계산
int count = -1; // 판매 대수
if (b < c) {
// 판매 대수 = 고정 비용 / (1대 가격 - 가변 비용) + 1
count = (int) ((a / (c - b)) + 1);
}
// 출력
System.out.println(count);
}
}
}