9333번: 돈 갚기
각 테스트 케이스 마다, 돈을 다 갚는데 몇 달이 걸리는지를 출력한다. 만약, 1200달이 넘어도 돈을 갚을 수 없다면, impossible을 출력한다.
www.acmicpc.net
9333번 : 돈 갚기
상근이는 선영이에게 B달러를 빌렸다.
이제 돈을 갚을 시간이다. 매월 초에 상근이가 내야하는 금액의 R 퍼센트가 이자로 붙는다. 상근이는 매월 말에 과외비 M달러를 받고, 이 금액 만큼 선영이에게 갚을 수 있다.
상근이는 선영이에게 더 이상 돈을 빌리지 않고, 상근이는 과외 이외의 일을 하지 않으며, 과외비는 인상되지 않는다.
이러한 경우에 상근이가 돈을 다 갚는데 몇 달이 걸리는지 구하는 프로그램을 작성하시오.
이자는 가까운 센트로 반올림한다. 100센트는 1달러이고, 0.5센트보다 크거나 같은 경우에 1센트로 올림, 나머지 경우에 버림한다.
입력
입력은 여러 개의 테스트 케이스로 이루어져 있다. 첫째 줄에는 테스트 케이스의 수가 주어지며, 1000을 넘지 않는다.
각 테스트 케이스는 한 줄로 이루어져 있고, R, B, M이 주어진다. 세 숫자는 모두 실수로 소수점 둘째 자리까지 주어지며, R ≤ 50.00, B, M ≤ 50000.00을 만족한다.
출력
각 테스트 케이스 마다, 돈을 다 갚는데 몇 달이 걸리는지를 출력한다. 만약, 1200달이 넘어도 돈을 갚을 수 없다면, impossible을 출력한다.
생각해 볼 점
쉽지만 까다로운 문제입니다.
사실 풀이법 자체는 문제에서 원하는 구현을 해주면 그만인데..
입력을 소수점(Float)으로 받는 순간부터 재앙이 시작됩니다.
우선 부동소수점 오차로 인해서 float을 낀 계산은 정확한 결과를 얻을 수 없습니다.
그런데, 입력 정도는 float으로 받아도 되지 않을까요?
예를 들어, 위와 같이 입력을 받았을 경우에도 문제가 생깁니다.
자, 아래와 같은 코드를 짰습니다. 결과는 무엇이 나올까요?
어라? 2.09 * 100을 해서 int에 넣어줬는데 어떻게 이럴수가 있습니까?
하지만, 부동소수점은 그런 것입니다.
따라서, 애초에 float으로 입력을 받지 않던지,
아니면 다음과 같이 int 변환해줘야 정확합니다.
이 점만 주의하면, 크게 어렵지 않은 문제입니다.
코드
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int T;
scanf("%d", &T);
while (T--)
{
long long R, B, M;
int R_dp, B_dp, M_dp;
scanf("%lld.%d %lld.%d %lld.%d", &R, &R_dp, &B, &B_dp, &M, &M_dp);
//센트로 치환
R = R * 100 + R_dp;
B = B * 100 + B_dp;
M = M * 100 + M_dp;
int month = 0;
while (0 < B && month <= 1200)
{
month++;
long long interest = R * B / 1000;
if (interest % 10 < 5) interest /= 10;
else interest = interest / 10 + 1;
if (M <= interest) month = 1201;
B += interest;
B -= M;
}
if (month == 1201) printf("impossible\n");
else printf("%d\n", month);
}
return 0;
}
그 외
'공부 및 정리 > 백준 코드' 카테고리의 다른 글
[C++]백준 - 14425번 문제 (0) | 2021.11.29 |
---|---|
[C++]백준 - 10266번 문제 (0) | 2021.11.23 |
[C++]백준 - 14725번 문제 (0) | 2021.11.22 |
[C++]백준 - 1284번 문제 (0) | 2021.11.22 |
[C++]백준 - 1212번 문제 (0) | 2021.11.20 |