https://www.acmicpc.net/problem/9333
9333번: 돈 갚기
각 테스트 케이스 마다, 돈을 다 갚는데 몇 달이 걸리는지를 출력한다. 만약, 1200달이 넘어도 돈을 갚을 수 없다면, impossible을 출력한다.
www.acmicpc.net
문제
상근이는 선영이에게 B달러를 빌렸다.
이제 돈을 갚을 시간이다. 매월 초에 상근이가 내야하는 금액의 R 퍼센트가 이자로 붙는다. 상근이는 매월 말에 과외비 M달러를 받고, 이 금액 만큼 선영이에게 갚을 수 있다.
상근이는 선영이에게 더 이상 돈을 빌리지 않고, 상근이는 과외 이외의 일을 하지 않으며, 과외비는 인상되지 않는다.
이러한 경우에 상근이가 돈을 다 갚는데 몇 달이 걸리는지 구하는 프로그램을 작성하시오.
이자는 가까운 센트로 반올림한다. 100센트는 1달러이고, 0.5센트보다 크거나 같은 경우에 1센트로 올림, 나머지 경우에 버림한다.
입력
입력은 여러 개의 테스트 케이스로 이루어져 있다. 첫째 줄에는 테스트 케이스의 수가 주어지며, 1000을 넘지 않는다.
각 테스트 케이스는 한 줄로 이루어져 있고, R, B, M이 주어진다. 세 숫자는 모두 실수로 소수점 둘째 자리까지 주어지며, R ≤ 50.00, B, M ≤ 50000.00을 만족한다.
출력
각 테스트 케이스 마다, 돈을 다 갚는데 몇 달이 걸리는지를 출력한다. 만약, 1200달이 넘어도 돈을 갚을 수 없다면, impossible을 출력한다.
(23.03.10)
교내 대회를 준비하기 위해 랜실디를 짬짬히 시간 내서 하는 중이다. 이 문제는 단순한 수학문제인 것 같은데, 참 이것저것 문제가 발생한다.
1. 부동소수점 오차 문제: 입력이 소수로 들어오기 때문에 부동소수점 오차가 발생한다. 원금 b와 소득 m의 경우는 소수점이 센트를 의미하기 때문에, 100을 곱해서 정수로 처리했지만, 이자는 소수로 처리하고 있기 때문에, 여기서 문제가 발생하는 것 같다.
2. (해결) 갚아야할 상환금이 int형을 벗어나는 경우가 존재한다.
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
void sol(int b, int m, double r) {
long long rest = b;
for (int i = 1; i <= 1200; i++) {
rest += (long long)(rest * r / 100 + 0.5);
rest -= m;
if (rest <= 0) {
cout << i << endl;
return;
}
}
cout << "impossible" << endl;
}
int main () {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int tc;
double b, r, m; // 원금, 이자, 소득
cin >> tc;
while(tc--) {
cin >> r >> b >> m;
sol(100 * b, 100 * m, r);
}
}
일단은 다른 할일 하러 실패한 기록을 적는다.
(23.03.13)
r = 50, b = 50000, m = 100 이하의 수에서 impossible이 아닌 70이 출력되는 현상을 발견했다. int형을 벗어나 long long형을 사용했는데, 이 값 역시 벗어났다. unsigned long long으로 바꾸었다. 그러더니 "틀렸습니다" 가 아닌 "출력 초과"가 발생했다.
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
#define FAIL "impossible"
void sol(int b, const int m, double r) {
unsigned long long rest = b;
for (int i = 1; i <= 1200; i++) {
rest += (unsigned long long)(rest * r / 100 + 0.5); // 이자 곱하고 반올림
rest -= m; // 상환
if (rest <= 0) {
cout << i << endl; // 다 갚았으면 끝
return;
}
}
cout << FAIL << endl; // 반복문 안에서 return이 안됐으면 실패
}
int main () {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int tc;
double b, r, m; // 원금, 이자, 소득
cin >> tc;
while(tc--) {
cin >> r >> b >> m;
sol(100 * b, 100 * m, r);
}
}
'coding_test > BAEKJOON' 카테고리의 다른 글
백준 2877번 C++ 풀이 (0) | 2023.04.25 |
---|---|
백준 2491번 C++ 풀이 (0) | 2023.03.28 |
백준 6800번 C++ 풀이 (0) | 2023.03.07 |
백준 21920번 C++ 풀이 (1) | 2023.02.05 |
백준 3005번 C++ 풀이 (1) | 2023.02.05 |