9단계 "수학"을 묶어서 한 게시글에 쓰려고 했으나.. 제가 수학을 정말 지지리 못하는 관계로 한 문제 한 문제가 힘겹기에 따로 게시글을 씁니다. 해당 문제는 자바로 풀었습니다.
해당 1712번 문제는 '손익분기점'을 구하라는 문제였다. 일단 9단계 "수학" 이라는 명칭부터가 수포자인 나로서는 굉장히 두려움으로 다가왔는데, 역시나 첫번째 문제부터 '손익분기점'이라는 용어가 나왔다.. 어떻게 보면 문제 자체는 쉽게 보일 수 있으나 메모리와 시간제한 싸움인 문제이다. 문제에서 "A, B, C는 21억 이하의 자연수이다." 라는 말과, 이 자연수 들을 담을 수 있는 int 자료형으로는 연산하기에 정말 매우 부족하다. 만약 a나 b가 정말 20억대 숫자라면, 연산을 2만 해도 바로 int형 크기를 초과해버린다. 처음에 나도 문제를 보고 "아..! 그럼 무한대로 정수를 다룰 수 있는 BigIntger 클래스를 활용하면 되겠구나!" 라고 생각했다. long 보다 큰 자료형, 무한대 크기를 다룰 때는 BigInteger을 쓰기 때문이다. 그치만 이 클래스를 알고 계셨다면 저처럼 문제를 헤맬 수도 있습니다. 왜냐면 제가 BigInetger가 이 문제의 해답 키의 역할을 해줄 줄 알고, 이것을 이용해 코드를 짰다가 메모리 초과만 3번정도 일어났기 때문입니다. 결국 이렇게 큰 수들을 연산시키면서 다루라는 문제는 아닌 것 같았다. 그래서 해당 조건에 대한 식을 메모장에 써봤다.
A+(B*i) < C*i (i는 카운터 횟수 변수)
그리고 이 식을 정리해봤다.
A < (C-B)i
따라서 i 또한 21억보다 낮아도 되니까 int변수로 선언할 수 있고, 연산 중 INT형 자료형(약 42억)보다 커질 경우도 없다(-> i가 최대 2일 경우에서 끝나므로). 그리고 이 조건이 항상 거짓이 되려면 B>=C 가 되어야 했고 이 경우가 문제에서 말하는 '손익분기점이 존재하지 않는 경우' 라고 말 할 수 있다. 이를 통해 코드를 짜 보면,
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.StringTokenizer;
public class break_even_point {
public static void main(String args[]) {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer stringTokenizer;
try {
int a = 0, b = 0, c = 0, counter = 1;
stringTokenizer = new StringTokenizer(br.readLine());
a = Integer.parseInt(stringTokenizer.nextToken());
b = Integer.parseInt(stringTokenizer.nextToken());
c = Integer.parseInt(stringTokenizer.nextToken());
if (b < c) {
while (true) {
if (a >= (c - b) * counter)
counter++;
else
break;
}
bw.write("" + counter);
} else
bw.write("-1");
bw.flush();
br.close();
bw.close();
} catch (Exception e) {
}
}
}
이 문제는 말 그대로 '알고있는 것' 보다는 '수학적 사고'를 요하는 문제였다. BigInteger 을 쓸 게 아니라, 식을 써보고 우리가 방정식을 풀듯이 식을 간단히 정리하여 메모리를 최대한 절약하는 방법을 구상했어야 했다.